diff --git a/sdk/eventgrid/azure-eventgrid/CHANGELOG.md b/sdk/eventgrid/azure-eventgrid/CHANGELOG.md index de82e38c93fd..6f336f5d3e8c 100644 --- a/sdk/eventgrid/azure-eventgrid/CHANGELOG.md +++ b/sdk/eventgrid/azure-eventgrid/CHANGELOG.md @@ -3,6 +3,7 @@ ## 2.0.0b6 (Unreleased) **Breaking Changes** + - `~azure.eventgrid.CloudEvent` is now removed in favor of `~azure.core.messaging.CloudEvent`. - All the `SystemEventNames` related to Azure Communication Service starting with `ACS****` are renamed to `Acs***` to honor pascal case. **Features** diff --git a/sdk/eventgrid/azure-eventgrid/README.md b/sdk/eventgrid/azure-eventgrid/README.md index 9629b210e18b..813cf6208a5e 100644 --- a/sdk/eventgrid/azure-eventgrid/README.md +++ b/sdk/eventgrid/azure-eventgrid/README.md @@ -145,7 +145,8 @@ This example publishes a Cloud event. ```Python import os from azure.core.credentials import AzureKeyCredential -from azure.eventgrid import EventGridPublisherClient, CloudEvent +from azure.core.messaging import CloudEvent +from azure.eventgrid import EventGridPublisherClient key = os.environ["CLOUD_ACCESS_KEY"] endpoint = os.environ["CLOUD_TOPIC_HOSTNAME"] @@ -166,7 +167,7 @@ client.send(event) This example consumes a message received from storage queue and deserializes it to a CloudEvent object. ```Python -from azure.eventgrid import CloudEvent +from azure.core.messaging import CloudEvent from azure.storage.queue import QueueServiceClient, BinaryBase64DecodePolicy import os import json @@ -244,7 +245,8 @@ Once the `tracer` and `exporter` are set, please follow the example below to sta ```python import os -from azure.eventgrid import EventGridPublisherClient, CloudEvent +from azure.eventgrid import EventGridPublisherClient +from azure.core.messaging import CloudEvent from azure.core.credentials import AzureKeyCredential hostname = os.environ['CLOUD_TOPIC_HOSTNAME'] diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/__init__.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/__init__.py index bb031e5ec320..1dc3655a13bb 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/__init__.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/__init__.py @@ -7,12 +7,11 @@ from ._publisher_client import EventGridPublisherClient from ._event_mappings import SystemEventNames from ._helpers import generate_sas -from ._models import CloudEvent, EventGridEvent +from ._models import EventGridEvent from ._version import VERSION __all__ = [ "EventGridPublisherClient", - "CloudEvent", "EventGridEvent", "generate_sas", "SystemEventNames", diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_helpers.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_helpers.py index 2780ceb569bb..a1a82d5bfac9 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_helpers.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_helpers.py @@ -18,6 +18,10 @@ from ._signature_credential_policy import EventGridSasCredentialPolicy from . import _constants as constants +from ._generated.models import ( + CloudEvent as InternalCloudEvent, +) + if TYPE_CHECKING: from datetime import datetime @@ -134,3 +138,25 @@ def _eventgrid_data_typecheck(event): "Data in EventGridEvent cannot be bytes. Please refer to" "https://docs.microsoft.com/en-us/azure/event-grid/event-schema" ) + +def _cloud_event_to_generated(cloud_event, **kwargs): + if isinstance(cloud_event.data, six.binary_type): + data_base64 = cloud_event.data + data = None + else: + data = cloud_event.data + data_base64 = None + return InternalCloudEvent( + id=cloud_event.id, + source=cloud_event.source, + type=cloud_event.type, + specversion=cloud_event.specversion, + data=data, + data_base64=data_base64, + time=cloud_event.time, + dataschema=cloud_event.dataschema, + datacontenttype=cloud_event.datacontenttype, + subject=cloud_event.subject, + additional_properties=cloud_event.extensions, + **kwargs + ) diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_models.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_models.py index 5154ed979fa4..3deb712dd9b1 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_models.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_models.py @@ -3,160 +3,16 @@ # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- # pylint:disable=protected-access -from typing import Union, Any, Dict +from typing import Any import datetime as dt import uuid -import json -import six from msrest.serialization import UTC from ._generated.models import ( EventGridEvent as InternalEventGridEvent, - CloudEvent as InternalCloudEvent, ) -class EventMixin(object): - """ - Mixin for the event models comprising of some helper methods. - """ - - @staticmethod - def _from_json(event, encode): - """ - Load the event into the json - :param dict eventgrid_event: The event to be deserialized. - :type eventgrid_event: Union[str, dict, bytes] - :param str encode: The encoding to be used. Defaults to 'utf-8' - """ - if isinstance(event, six.binary_type): - event = json.loads(event.decode(encode)) - elif isinstance(event, six.string_types): - event = json.loads(event) - return event - - -class CloudEvent(EventMixin): # pylint:disable=too-many-instance-attributes - """Properties of an event published to an Event Grid topic using the CloudEvent 1.0 Schema. - - All required parameters must be populated in order to send to Azure. - If data is of binary type, data_base64 can be used alternatively. Note that data and data_base64 - cannot be present at the same time. - - :param source: Required. Identifies the context in which an event happened. The combination of id and source must - be unique for each distinct event. If publishing to a domain topic, source must be the domain name. - :type source: str - :param type: Required. Type of event related to the originating occurrence. - :type type: str - :keyword data: Optional. Event data specific to the event type. Only one of the `data` or `data_base64` - argument must be present. If data is of bytes type, it will be sent as data_base64 in the outgoing request. - :type data: object - :keyword time: Optional. The time (in UTC) the event was generated, in RFC3339 format. - :type time: ~datetime.datetime - :keyword dataschema: Optional. Identifies the schema that data adheres to. - :type dataschema: str - :keyword datacontenttype: Optional. Content type of data value. - :type datacontenttype: str - :keyword subject: Optional. This describes the subject of the event in the context of the event producer - (identified by source). - :type subject: str - :keyword specversion: Optional. The version of the CloudEvent spec. Defaults to "1.0" - :type specversion: str - :keyword id: Optional. An identifier for the event. The combination of id and source must be - unique for each distinct event. If not provided, a random UUID will be generated and used. - :type id: Optional[str] - :keyword data_base64: Optional. Event data specific to the event type if the data is of bytes type. - Only data of bytes type is accepted by `data-base64` and only one of the `data` or `data_base64` argument - must be present. - :type data_base64: bytes - :ivar source: Identifies the context in which an event happened. The combination of id and source must - be unique for each distinct event. If publishing to a domain topic, source must be the domain name. - :vartype source: str - :ivar data: Event data specific to the event type. - :vartype data: object - :ivar data_base64: Event data specific to the event type if the data is of bytes type. - :vartype data_base64: bytes - :ivar type: Type of event related to the originating occurrence. - :vartype type: str - :ivar time: The time (in UTC) the event was generated, in RFC3339 format. - :vartype time: ~datetime.datetime - :ivar dataschema: Identifies the schema that data adheres to. - :vartype dataschema: str - :ivar datacontenttype: Content type of data value. - :vartype datacontenttype: str - :ivar subject: This describes the subject of the event in the context of the event producer - (identified by source). - :vartype subject: str - :ivar specversion: Optional. The version of the CloudEvent spec. Defaults to "1.0" - :vartype specversion: str - :ivar id: An identifier for the event. The combination of id and source must be - unique for each distinct event. If not provided, a random UUID will be generated and used. - :vartype id: Optional[str] - """ - - def __init__(self, source, type, **kwargs): # pylint: disable=redefined-builtin - # type: (str, str, Any) -> None - self.source = source - self.type = type - self.specversion = kwargs.pop("specversion", "1.0") - self.id = kwargs.pop("id", str(uuid.uuid4())) - self.time = kwargs.pop("time", dt.datetime.now(UTC()).isoformat()) - self.data = kwargs.pop("data", None) - self.datacontenttype = kwargs.pop("datacontenttype", None) - self.dataschema = kwargs.pop("dataschema", None) - self.subject = kwargs.pop("subject", None) - self.data_base64 = kwargs.pop("data_base64", None) - self.extensions = {} - self.extensions.update(dict(kwargs.pop("extensions", {}))) - if self.data is not None and self.data_base64 is not None: - 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_generated(cls, cloud_event, **kwargs): - # type: (Union[str, Dict, bytes], Any) -> CloudEvent - generated = InternalCloudEvent.deserialize(cloud_event) - if generated.additional_properties: - extensions = dict(generated.additional_properties) - kwargs.setdefault("extensions", extensions) - return cls( - id=generated.id, - source=generated.source, - type=generated.type, - specversion=generated.specversion, - data=generated.data or generated.data_base64, - time=generated.time, - dataschema=generated.dataschema, - datacontenttype=generated.datacontenttype, - subject=generated.subject, - **kwargs - ) - - def _to_generated(self, **kwargs): - if isinstance(self.data, six.binary_type): - data_base64 = self.data - data = None - else: - data = self.data - data_base64 = None - return InternalCloudEvent( - id=self.id, - source=self.source, - type=self.type, - specversion=self.specversion, - data=data, - data_base64=self.data_base64 or data_base64, - time=self.time, - dataschema=self.dataschema, - datacontenttype=self.datacontenttype, - subject=self.subject, - additional_properties=self.extensions, - **kwargs - ) - - -class EventGridEvent(InternalEventGridEvent, EventMixin): +class EventGridEvent(InternalEventGridEvent): """Properties of an event published to an Event Grid topic using the EventGrid Schema. Variables are only populated by the server, and will be ignored when sending a request. diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_publisher_client.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_publisher_client.py index 20b8b04df3b0..482699f9068a 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_publisher_client.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_publisher_client.py @@ -21,14 +21,16 @@ HttpLoggingPolicy, UserAgentPolicy, ) +from azure.core.messaging import CloudEvent -from ._models import CloudEvent, EventGridEvent +from ._models import EventGridEvent from ._helpers import ( _get_endpoint_only_fqdn, _get_authentication_policy, _is_cloud_event, _is_eventgrid_event, _eventgrid_data_typecheck, + _cloud_event_to_generated, ) from ._generated._event_grid_publisher_client import ( EventGridPublisherClient as EventGridPublisherClientImpl, @@ -179,7 +181,7 @@ def send(self, events, **kwargs): if isinstance(events[0], CloudEvent) or _is_cloud_event(events[0]): try: events = [ - cast(CloudEvent, e)._to_generated(**kwargs) for e in events # pylint: disable=protected-access + _cloud_event_to_generated(e, **kwargs) for e in events # pylint: disable=protected-access ] except AttributeError: pass # means it's a dictionary diff --git a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_publisher_client_async.py b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_publisher_client_async.py index b6abc8d3f1a8..b22c97c280ef 100644 --- a/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_publisher_client_async.py +++ b/sdk/eventgrid/azure-eventgrid/azure/eventgrid/aio/_publisher_client_async.py @@ -9,6 +9,7 @@ from typing import Any, Union, List, Dict, cast from azure.core.credentials import AzureKeyCredential, AzureSasCredential from azure.core.tracing.decorator_async import distributed_trace_async +from azure.core.messaging import CloudEvent from azure.core.pipeline.policies import ( RequestIdPolicy, HeadersPolicy, @@ -23,13 +24,14 @@ UserAgentPolicy, ) from .._policies import CloudEventDistributedTracingPolicy -from .._models import CloudEvent, EventGridEvent +from .._models import EventGridEvent from .._helpers import ( _get_endpoint_only_fqdn, _get_authentication_policy, _is_cloud_event, _is_eventgrid_event, _eventgrid_data_typecheck, + _cloud_event_to_generated, ) from .._generated.aio import EventGridPublisherClient as EventGridPublisherClientAsync from .._version import VERSION @@ -172,7 +174,7 @@ async def send(self, events: SendType, **kwargs: Any) -> None: if isinstance(events[0], CloudEvent) or _is_cloud_event(events[0]): try: events = [ - cast(CloudEvent, e)._to_generated(**kwargs) for e in events # pylint: disable=protected-access + _cloud_event_to_generated(e, **kwargs) for e in events # pylint: disable=protected-access ] except AttributeError: pass # means it's a dictionary diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cloud_event_using_dict_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cloud_event_using_dict_async.py index db958983fb53..63f36c5ecb80 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cloud_event_using_dict_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_cloud_event_using_dict_async.py @@ -17,7 +17,7 @@ """ import os import asyncio -from azure.eventgrid import CloudEvent +from azure.core.messaging import CloudEvent from azure.eventgrid.aio import EventGridPublisherClient from azure.core.credentials import AzureKeyCredential diff --git a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_using_cloud_events_1.0_schema_async.py b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_using_cloud_events_1.0_schema_async.py index 24a881e51eb5..f67bf1a19df5 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_using_cloud_events_1.0_schema_async.py +++ b/sdk/eventgrid/azure-eventgrid/samples/async_samples/sample_publish_events_using_cloud_events_1.0_schema_async.py @@ -17,7 +17,7 @@ # [START publish_cloud_event_to_topic_async] import os import asyncio -from azure.eventgrid import CloudEvent +from azure.core.messaging import CloudEvent from azure.eventgrid.aio import EventGridPublisherClient from azure.core.credentials import AzureKeyCredential diff --git a/sdk/eventgrid/azure-eventgrid/samples/consume_samples/consume_cloud_events_from_storage_queue.py b/sdk/eventgrid/azure-eventgrid/samples/consume_samples/consume_cloud_events_from_storage_queue.py index 919183405d4d..511188b66df5 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/consume_samples/consume_cloud_events_from_storage_queue.py +++ b/sdk/eventgrid/azure-eventgrid/samples/consume_samples/consume_cloud_events_from_storage_queue.py @@ -14,7 +14,7 @@ 3) STORAGE_QUEUE_NAME: The name of the storage queue. """ -from azure.eventgrid import CloudEvent +from azure.core.messaging import CloudEvent from azure.storage.queue import QueueServiceClient, BinaryBase64DecodePolicy import os import json diff --git a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_custom_topic_sample.py b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_custom_topic_sample.py index 108904daa05c..fbd7aa72a024 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_custom_topic_sample.py +++ b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_custom_topic_sample.py @@ -20,7 +20,8 @@ import time from azure.core.credentials import AzureKeyCredential -from azure.eventgrid import EventGridPublisherClient, CloudEvent +from azure.core.messaging import CloudEvent +from azure.eventgrid import EventGridPublisherClient key = os.environ.get("CLOUD_ACCESS_KEY") endpoint = os.environ["CLOUD_TOPIC_HOSTNAME"] diff --git a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_domain_topic_sample.py b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_domain_topic_sample.py index 9f71e67c752f..3cc781ac04be 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_domain_topic_sample.py +++ b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_cloud_events_to_domain_topic_sample.py @@ -22,7 +22,8 @@ import time from azure.core.credentials import AzureKeyCredential -from azure.eventgrid import EventGridPublisherClient, CloudEvent +from azure.core.messaging import CloudEvent +from azure.eventgrid import EventGridPublisherClient domain_key = os.environ["DOMAIN_ACCESS_KEY"] domain_endpoint = os.environ["DOMAIN_TOPIC_HOSTNAME"] diff --git a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_with_shared_access_signature_sample.py b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_with_shared_access_signature_sample.py index 5782a2c65168..4d147a1aa75b 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_with_shared_access_signature_sample.py +++ b/sdk/eventgrid/azure-eventgrid/samples/publish_samples/publish_with_shared_access_signature_sample.py @@ -21,7 +21,8 @@ from datetime import datetime, timedelta from azure.core.credentials import AzureSasCredential -from azure.eventgrid import EventGridPublisherClient, CloudEvent, generate_sas +from azure.core.messaging import CloudEvent +from azure.eventgrid import EventGridPublisherClient, generate_sas key = os.environ["CLOUD_ACCESS_KEY"] endpoint = os.environ["CLOUD_TOPIC_HOSTNAME"] diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_consume_custom_payload.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_consume_custom_payload.py index 70ae25278024..b9559e94ffd7 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_consume_custom_payload.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_consume_custom_payload.py @@ -12,7 +12,7 @@ python sample_consume_custom_payload.py """ -from azure.eventgrid import CloudEvent +from azure.core.messaging import CloudEvent import json # all types of CloudEvents below produce same DeserializedEvent diff --git a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_using_cloud_events_1.0_schema.py b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_using_cloud_events_1.0_schema.py index c2147ce66238..f27cf822e6a5 100644 --- a/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_using_cloud_events_1.0_schema.py +++ b/sdk/eventgrid/azure-eventgrid/samples/sync_samples/sample_publish_events_using_cloud_events_1.0_schema.py @@ -16,8 +16,9 @@ """ # [START publish_cloud_event_to_topic] import os -from azure.eventgrid import EventGridPublisherClient, CloudEvent +from azure.eventgrid import EventGridPublisherClient from azure.core.credentials import AzureKeyCredential +from azure.core.messaging import CloudEvent topic_key = os.environ["CLOUD_ACCESS_KEY"] endpoint = os.environ["CLOUD_TOPIC_HOSTNAME"] diff --git a/sdk/eventgrid/azure-eventgrid/setup.py b/sdk/eventgrid/azure-eventgrid/setup.py index 205d3ceec27c..36e7f2dee297 100644 --- a/sdk/eventgrid/azure-eventgrid/setup.py +++ b/sdk/eventgrid/azure-eventgrid/setup.py @@ -82,7 +82,7 @@ ]), install_requires=[ 'msrest>=0.6.19', - 'azure-core<2.0.0,>=1.10.0', + 'azure-core<2.0.0,>=1.12.0', ], extras_require={ ":python_version<'3.0'": ['azure-nspkg'], diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_cloud_event_tracing.py b/sdk/eventgrid/azure-eventgrid/tests/test_cloud_event_tracing.py index 9032189d0658..feed7d9865d8 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_cloud_event_tracing.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_cloud_event_tracing.py @@ -12,7 +12,7 @@ PipelineContext ) from azure.core.pipeline.transport import HttpRequest -from azure.eventgrid import CloudEvent +from azure.core.messaging import CloudEvent from azure.eventgrid._policies import CloudEventDistributedTracingPolicy from _mocks import ( cloud_storage_dict diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py index 5792a07dec03..3f5bd0702da4 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client.py @@ -18,7 +18,10 @@ from azure_devtools.scenario_tests import ReplayableTest from azure.core.credentials import AzureKeyCredential, AzureSasCredential -from azure.eventgrid import EventGridPublisherClient, CloudEvent, EventGridEvent, generate_sas +from azure.core.messaging import CloudEvent +from azure.core.serialization import NULL +from azure.eventgrid import EventGridPublisherClient, EventGridEvent, generate_sas +from azure.eventgrid._helpers import _cloud_event_to_generated from eventgrid_preparer import ( CachedEventGridTopicPreparer @@ -132,32 +135,32 @@ def test_send_cloud_event_data_dict(self, resource_group, eventgrid_topic, event ) client.send(cloud_event) + @pytest.mark.skip("https://github.com/Azure/azure-sdk-for-python/issues/16993") @CachedResourceGroupPreparer(name_prefix='eventgridtest') @CachedEventGridTopicPreparer(name_prefix='cloudeventgridtest') - def test_send_cloud_event_data_base64_using_data(self, resource_group, eventgrid_topic, eventgrid_topic_primary_key, eventgrid_topic_endpoint): + def test_send_cloud_event_data_NULL(self, resource_group, eventgrid_topic, eventgrid_topic_primary_key, eventgrid_topic_endpoint): akc_credential = AzureKeyCredential(eventgrid_topic_primary_key) client = EventGridPublisherClient(eventgrid_topic_endpoint, akc_credential) cloud_event = CloudEvent( source = "http://samplesource.dev", - data = b'cloudevent', + data = NULL, type="Sample.Cloud.Event" ) - + def callback(request): req = json.loads(request.http_request.body) - assert req[0].get("data_base64") is not None assert req[0].get("data") is None - client.send(cloud_event, raw_response_hook=callback) + client.send(cloud_event, raw_request_hook=callback) @CachedResourceGroupPreparer(name_prefix='eventgridtest') @CachedEventGridTopicPreparer(name_prefix='cloudeventgridtest') - def test_send_cloud_event_bytes_using_data_base64(self, resource_group, eventgrid_topic, eventgrid_topic_primary_key, eventgrid_topic_endpoint): + def test_send_cloud_event_data_base64_using_data(self, resource_group, eventgrid_topic, eventgrid_topic_primary_key, eventgrid_topic_endpoint): akc_credential = AzureKeyCredential(eventgrid_topic_primary_key) client = EventGridPublisherClient(eventgrid_topic_endpoint, akc_credential) cloud_event = CloudEvent( source = "http://samplesource.dev", - data_base64 = b'cloudevent', + data = b'cloudevent', type="Sample.Cloud.Event" ) @@ -168,9 +171,8 @@ def callback(request): client.send(cloud_event, raw_response_hook=callback) - def test_send_cloud_event_fails_on_providing_data_and_b64(self): - with pytest.raises(ValueError, match="data and data_base64 cannot be provided at the same time*"): + with pytest.raises(ValueError, match="Unexpected keyword arguments data_base64.*"): cloud_event = CloudEvent( source = "http://samplesource.dev", data_base64 = b'cloudevent', @@ -236,15 +238,15 @@ def test_send_cloud_event_data_with_extensions(self, resource_group, eventgrid_t data = "cloudevent", type="Sample.Cloud.Event", extensions={ - 'reason_code':204, + 'reasoncode':204, 'extension':'hello' } ) client.send([cloud_event]) - internal = cloud_event._to_generated().serialize() - assert 'reason_code' in internal + internal = _cloud_event_to_generated(cloud_event).serialize() + assert 'reasoncode' in internal assert 'extension' in internal - assert internal['reason_code'] == 204 + assert internal['reasoncode'] == 204 @CachedResourceGroupPreparer(name_prefix='eventgridtest') @CachedEventGridTopicPreparer(name_prefix='cloudeventgridtest') diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py index 040866a36ac2..33a6536245b1 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_eg_publisher_client_async.py @@ -8,6 +8,7 @@ import asyncio import sys import os +import json import pytest from datetime import timedelta from msrest.serialization import UTC @@ -17,8 +18,11 @@ from azure_devtools.scenario_tests import ReplayableTest from azure.core.credentials import AzureKeyCredential, AzureSasCredential -from azure.eventgrid import CloudEvent, EventGridEvent, generate_sas +from azure.core.messaging import CloudEvent +from azure.core.serialization import NULL +from azure.eventgrid import EventGridEvent, generate_sas from azure.eventgrid.aio import EventGridPublisherClient +from azure.eventgrid._helpers import _cloud_event_to_generated from eventgrid_preparer import ( CachedEventGridTopicPreparer @@ -174,15 +178,15 @@ async def test_send_cloud_event_data_with_extensions(self, resource_group, event data = "cloudevent", type="Sample.Cloud.Event", extensions={ - 'reason_code':204, + 'reasoncode':204, 'extension':'hello' } ) await client.send([cloud_event]) - internal = cloud_event._to_generated().serialize() - assert 'reason_code' in internal + internal = _cloud_event_to_generated(cloud_event).serialize() + assert 'reasoncode' in internal assert 'extension' in internal - assert internal['reason_code'] == 204 + assert internal['reasoncode'] == 204 @CachedResourceGroupPreparer(name_prefix='eventgridtest') @@ -213,6 +217,24 @@ async def test_send_cloud_event_data_none(self, resource_group, eventgrid_topic, ) await client.send(cloud_event) + @pytest.mark.skip("https://github.com/Azure/azure-sdk-for-python/issues/16993") + @CachedResourceGroupPreparer(name_prefix='eventgridtest') + @CachedEventGridTopicPreparer(name_prefix='cloudeventgridtest') + @pytest.mark.asyncio + async def test_send_cloud_event_data_NULL(self, resource_group, eventgrid_topic, eventgrid_topic_primary_key, eventgrid_topic_endpoint): + akc_credential = AzureKeyCredential(eventgrid_topic_primary_key) + client = EventGridPublisherClient(eventgrid_topic_endpoint, akc_credential) + cloud_event = CloudEvent( + source = "http://samplesource.dev", + data = NULL, + type="Sample.Cloud.Event" + ) + def callback(request): + req = json.loads(request.http_request.body) + assert req[0].get("data") is None + + await client.send(cloud_event, raw_request_hook=callback) + @CachedResourceGroupPreparer(name_prefix='eventgridtest') @CachedEventGridTopicPreparer(name_prefix='eventgridtest') @pytest.mark.asyncio diff --git a/sdk/eventgrid/azure-eventgrid/tests/test_serialization.py b/sdk/eventgrid/azure-eventgrid/tests/test_serialization.py index d84d61f55cb4..bf463d27b0cb 100644 --- a/sdk/eventgrid/azure-eventgrid/tests/test_serialization.py +++ b/sdk/eventgrid/azure-eventgrid/tests/test_serialization.py @@ -14,9 +14,10 @@ from devtools_testutils import AzureMgmtTestCase from msrest.serialization import UTC -from azure.eventgrid import CloudEvent, EventGridEvent +from azure.core.messaging import CloudEvent from azure.eventgrid._generated import models as internal_models -from azure.eventgrid import SystemEventNames +from azure.eventgrid._helpers import _cloud_event_to_generated +from azure.eventgrid import SystemEventNames, EventGridEvent from _mocks import ( cloud_storage_dict, cloud_storage_string, @@ -39,16 +40,14 @@ def test_cloud_event_serialization_extension_bytes(self, **kwargs): source="http://samplesource.dev", data=data, type="Sample.Cloud.Event", - foo="bar", extensions={'e1':1, 'e2':2} ) cloud_event.subject = "subject" # to test explicit setting of prop encoded = base64.b64encode(data).decode('utf-8') - internal = cloud_event._to_generated() + internal = _cloud_event_to_generated(cloud_event) assert internal.additional_properties is not None - assert 'foo' not in internal.additional_properties assert 'e1' in internal.additional_properties json = internal.serialize() @@ -72,15 +71,13 @@ def test_cloud_event_serialization_extension_string(self, **kwargs): source="http://samplesource.dev", data=data, type="Sample.Cloud.Event", - foo="bar", extensions={'e1':1, 'e2':2} ) cloud_event.subject = "subject" # to test explicit setting of prop - internal = cloud_event._to_generated() + internal = _cloud_event_to_generated(cloud_event) assert internal.additional_properties is not None - assert 'foo' not in internal.additional_properties assert 'e1' in internal.additional_properties json = internal.serialize() diff --git a/shared_requirements.txt b/shared_requirements.txt index c16a49b98418..95d74b89fef8 100644 --- a/shared_requirements.txt +++ b/shared_requirements.txt @@ -169,7 +169,6 @@ opentelemetry-sdk==0.17b0 #override azure-servicebus msrest>=0.6.17,<2.0.0 #override azure-servicebus azure-core<2.0.0,>=1.6.0 #override azure-search-documents msrest>=0.6.10 -#override azure-eventgrid azure-core<2.0.0,>=1.7.0 #override azure-synapse-accesscontrol azure-core>=1.6.0,<2.0.0 #override azure-synapse-spark azure-core>=1.6.0,<2.0.0 #override azure-synapse-artifacts azure-core>=1.6.0,<2.0.0 @@ -178,7 +177,7 @@ opentelemetry-sdk==0.17b0 #override azure-data-tables msrest>=0.6.10 #override azure-ai-anomalydetector azure-core>=1.6.0,<2.0.0 #override azure-eventgrid msrest>=0.6.19 -#override azure-eventgrid azure-core<2.0.0,>=1.10.0 +#override azure-eventgrid azure-core<2.0.0,>=1.12.0 #override azure-communication-chat msrest>=0.6.0 #override azure-communication-sms msrest>=0.6.0 #override azure-communication-phonenumbers msrest>=0.6.0