From 78fa602fdac606816619e8715d703efd3b7e78e3 Mon Sep 17 00:00:00 2001 From: Rakshith Bhyravabhotla Date: Tue, 2 Feb 2021 16:49:09 -0800 Subject: [PATCH 1/3] initial --- .../azure/eventgrid/_models.py | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_models.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_models.py index c886e78553a6..b9188444fdb0 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_models.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_models.py @@ -106,6 +106,31 @@ def __init__(self, source, type, **kwargs): # pylint: disable=redefined-builtin raise ValueError("data and data_base64 cannot be provided at the same time.\ Use data_base64 only if you are sending bytes, and use data otherwise.") + @classmethod + def from_dict(cls, event, **kwargs): + # type: (Dict, Any) -> CloudEvent + """ + Returns the deserialized CloudEvent object when a dict is provided. + + :param event: The dict representation of the event which needs to be deserialized. + :type event: dict + + :rtype: CloudEvent + """ + return cls( + id=event.pop("id", None), + source=event.pop("source", None), + type=event.pop("type", None), + specversion=event.pop("specversion", None), + data=event.pop("data", None) or event.pop("data_base64", None), + time=event.pop("time", None), + dataschema=event.pop("dataschema", None), + datacontenttype=event.pop("datacontenttype", None), + subject=event.pop("subject", None), + extensions=event, + **kwargs + ) + @classmethod def _from_generated(cls, cloud_event, **kwargs): # type: (Union[str, Dict, bytes], Any) -> CloudEvent @@ -228,3 +253,26 @@ def __init__(self, subject, event_type, data, data_version, **kwargs): kwargs.setdefault('data_version', data_version) super(EventGridEvent, self).__init__(**kwargs) + + @classmethod + def from_dict(cls, event, **kwargs): + # type: (Dict, Any) -> EventGridEvent + """ + Returns the deserialized EventGridEvent object when a dict is provided. + + :param event: The dict representation of the event which needs to be deserialized. + :type event: dict + + :rtype: EventGridEvent + """ + return cls( + id=event.get("id", None), + subject=event.get("subject", None), + topic=event.get("topic", None), + data_version=event.get("dataVersion", None), + data=event.get("data", None), + event_time=event.get("eventTime", None), + event_type=event.get("eventType", None), + metadata_version=event.get("metadataVersion", None), + **kwargs + ) From ef9a2f034fd2a135940abca0540b7527232e82a7 Mon Sep 17 00:00:00 2001 From: Rakshith Bhyravabhotla Date: Tue, 2 Feb 2021 23:39:53 -0800 Subject: [PATCH 2/3] add tests --- sdk/eventgrid/azure-eventgrid/CHANGELOG.md | 3 + .../azure/eventgrid/_helpers.py | 9 +++ .../azure/eventgrid/_models.py | 3 +- sdk/eventgrid/azure-eventgrid/tests/_mocks.py | 40 +++++-------- .../azure-eventgrid/tests/test_from_dict.py | 56 +++++++++++++++++++ 5 files changed, 84 insertions(+), 27 deletions(-) create mode 100644 sdk/eventgrid/azure-eventgrid/tests/test_from_dict.py diff --git a/sdk/eventgrid/azure-eventgrid/CHANGELOG.md b/sdk/eventgrid/azure-eventgrid/CHANGELOG.md index 6ab909fe9c25..b3362994556a 100644 --- a/sdk/eventgrid/azure-eventgrid/CHANGELOG.md +++ b/sdk/eventgrid/azure-eventgrid/CHANGELOG.md @@ -2,6 +2,9 @@ ## 2.0.0b5 (Unreleased) + **Features** + - `CloudEvent` and `EventGridEvent` now have a `from_dict` method which deserializes a dict representation into corresponding object. + **Breaking Changes** - `EventGridSharedAccessSignatureCredential` is deprecated in favor of `AzureSasCredential`. - `azure.eventgrid.models` namespace along with all the models in it are now removed. `azure.eventgrid.SystemEventNames` can be used to get the event model type mapping. diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_helpers.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_helpers.py index 4d77076183f4..b85369d9afbb 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_helpers.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_helpers.py @@ -110,3 +110,12 @@ def _eventgrid_data_typecheck(event): if isinstance(data, six.binary_type): raise TypeError("Data in EventGridEvent cannot be bytes. Please refer to"\ "https://docs.microsoft.com/en-us/azure/event-grid/event-schema") + +def _decode(content): + try: + return base64.b64decode(content.encode('utf-8')) + except (ValueError, TypeError) as error: + # ValueError for Python 3, TypeError for Python 2 + raise ValueError( + message="Data is not valid base 64.", + error=error) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_models.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_models.py index b9188444fdb0..53275f0855ce 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_models.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_models.py @@ -9,6 +9,7 @@ import json import six from msrest.serialization import UTC +from ._helpers import _decode from ._generated.models import EventGridEvent as InternalEventGridEvent, CloudEvent as InternalCloudEvent @@ -122,7 +123,7 @@ def from_dict(cls, event, **kwargs): source=event.pop("source", None), type=event.pop("type", None), specversion=event.pop("specversion", None), - data=event.pop("data", None) or event.pop("data_base64", None), + data=event.pop("data", None) or _decode(event.pop("data_base64", None)), time=event.pop("time", None), dataschema=event.pop("dataschema", None), datacontenttype=event.pop("datacontenttype", None), diff --git a/sdk/eventgrid/azure-eventgrid/tests/_mocks.py b/sdk/eventgrid/azure-eventgrid/tests/_mocks.py index 107d6d6175ed..8baf5a81a558 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/_mocks.py +++ b/sdk/eventgrid/azure-eventgrid/tests/_mocks.py @@ -1,6 +1,3 @@ -import json - - # storage cloud event cloud_storage_dict = { "id":"a0517898-9fa4-4e70-b4a3-afda1dd68672", @@ -21,20 +18,28 @@ "time":"2020-08-07T01:11:49.765846Z", "specversion":"1.0" } -cloud_storage_string = json.dumps(cloud_storage_dict) -cloud_storage_bytes = cloud_storage_string.encode("utf-8") # custom cloud event -cloud_custom_dict = { +cloud_custom_dict_base64 = { "id":"de0fd76c-4ef4-4dfb-ab3a-8f24a307e033", "source":"https://egtest.dev/cloudcustomevent", - "data":{"team": "event grid squad"}, + "data_base64":'Y2xvdWRldmVudA==', "type":"Azure.Sdk.Sample", "time":"2020-08-07T02:06:08.11969Z", "specversion":"1.0" } -cloud_custom_string = json.dumps(cloud_custom_dict) -cloud_custom_bytes = cloud_custom_string.encode("utf-8") + +cloud_custom_dict_with_extensions = { + "id":"de0fd76c-4ef4-4dfb-ab3a-8f24a307e033", + "source":"https://egtest.dev/cloudcustomevent", + "data":{"team": "event grid squad"}, + "type":"Azure.Sdk.Sample", + "time":"2020-08-07T02:06:08.11969Z", + "specversion":"1.0", + "ext1": "example", + "ext2": "example2" +} + # storage eg event eg_storage_dict = { @@ -58,20 +63,3 @@ "eventTime":"2020-08-07T02:28:23.867525Z", "topic":"/subscriptions/faa080af-c1d8-40ad-9cce-e1a450ca5b57/resourceGroups/t-swpill-test/providers/Microsoft.EventGrid/topics/eventgridegsub" } - -eg_storage_string = json.dumps(eg_storage_dict) -eg_storage_bytes = eg_storage_string.encode("utf-8") - -# custom eg event -eg_custom_dict = { - "id":"3a30afef-b604-4b67-973e-7dfff7e178a7", - "subject":"Test EG Custom Event", - "data":{"team":"event grid squad"}, - "eventType":"Azure.Sdk.Sample", - "dataVersion":"2.0", - "metadataVersion":"1", - "eventTime":"2020-08-07T02:19:05.16916Z", - "topic":"/subscriptions/f8aa80ae-d1c8-60ad-9bce-e1a850ba5b67/resourceGroups/sample-resource-group-test/providers/Microsoft.EventGrid/topics/egtopicsamplesub" -} -eg_custom_string = json.dumps(eg_custom_dict) -eg_custom_bytes = eg_custom_string.encode("utf-8") diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_from_dict.py b/sdk/eventgrid/azure-eventgrid/tests/test_from_dict.py new file mode 100644 index 000000000000..55005b60176d --- /dev/null +++ b/sdk/eventgrid/azure-eventgrid/tests/test_from_dict.py @@ -0,0 +1,56 @@ +import logging +import sys +import os +import pytest +import json + +from azure.eventgrid import CloudEvent, EventGridEvent +from devtools_testutils import AzureMgmtTestCase +from _mocks import ( + cloud_storage_dict, + cloud_custom_dict_base64, + cloud_custom_dict_with_extensions, + eg_storage_dict +) + +class EventGridDeserializerTests(AzureMgmtTestCase): + + # Cloud Event tests + def test_eg_consumer_cloud_storage_dict(self, **kwargs): + event = CloudEvent.from_dict(cloud_storage_dict) + assert event.data == { + "api":"PutBlockList", + "client_request_id":"6d79dbfb-0e37-4fc4-981f-442c9ca65760", + "request_id":"831e1650-001e-001b-66ab-eeb76e000000", + "e_tag":"0x8D4BCC2E4835CD0", + "content_type":"application/octet-stream", + "content_length":524288, + "blob_type":"BlockBlob", + "url":"https://oc2d2817345i60006.blob.core.windows.net/oc2d2817345i200097container/oc2d2817345i20002296blob", + "sequencer":"00000000000004420000000000028963", + "storage_diagnostics":{"batchId":"b68529f3-68cd-4744-baa4-3c0498ec19f0"} + } + assert event.specversion == "1.0" + assert event.__class__ == CloudEvent + + + def test_cloud_custom_dict_with_extensions(self, **kwargs): + event = CloudEvent.from_dict(cloud_custom_dict_with_extensions) + assert event.data == {"team": "event grid squad"} + assert event.__class__ == CloudEvent + assert event.extensions == {"ext1": "example", "ext2": "example2"} + + def test_cloud_custom_dict_base64(self, **kwargs): + event = CloudEvent.from_dict(cloud_custom_dict_base64) + assert event.data == b'cloudevent' + assert event.data_base64 == None + assert event.specversion == "1.0" + assert event.__class__ == CloudEvent + + # EG Event tests + + def test_eg_storage_from_dict(self, **kwargs): + event = EventGridEvent.from_dict(eg_storage_dict) + assert event.__class__ == EventGridEvent + assert event.event_time == "2020-08-07T02:28:23.867525Z" + assert event.event_type == "Microsoft.Storage.BlobCreated" From 88ce6bec834ee0be12b0fb3494b99c22bba1ff99 Mon Sep 17 00:00:00 2001 From: Rakshith Bhyravabhotla Date: Wed, 3 Feb 2021 15:22:18 -0800 Subject: [PATCH 3/3] import errror --- sdk/eventgrid/azure-eventgrid/tests/test_serialization.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_serialization.py b/sdk/eventgrid/azure-eventgrid/tests/test_serialization.py index 5bed9c1c9212..df60c6f665a3 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_serialization.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_serialization.py @@ -17,11 +17,6 @@ from azure.eventgrid import CloudEvent, EventGridEvent from azure.eventgrid._generated import models as internal_models from azure.eventgrid import SystemEventNames -from _mocks import ( - cloud_storage_dict, - cloud_storage_string, - cloud_storage_bytes, - ) class EventGridSerializationTests(AzureMgmtTestCase):