From 9b6db7e50b6b5f55a8546d6dbbc6c0bc53b99d7e Mon Sep 17 00:00:00 2001 From: "Adam Ling (MSFT)" Date: Wed, 3 Mar 2021 05:40:48 -0800 Subject: [PATCH 1/3] add a logging to warn the usage of partition key of non-string type --- .../azure-eventhub/azure/eventhub/_producer_client.py | 11 +++++++++++ .../azure/eventhub/aio/_producer_client_async.py | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/sdk/eventhub/azure-eventhub/azure/eventhub/_producer_client.py b/sdk/eventhub/azure-eventhub/azure/eventhub/_producer_client.py index c3f139337eb9..4b0a0960d437 100644 --- a/sdk/eventhub/azure-eventhub/azure/eventhub/_producer_client.py +++ b/sdk/eventhub/azure-eventhub/azure/eventhub/_producer_client.py @@ -246,6 +246,12 @@ def send_batch(self, event_data_batch, **kwargs): """ partition_id = kwargs.get("partition_id") partition_key = kwargs.get("partition_key") + + if partition_key and not isinstance(partition_key, str): + _LOGGER.info("WARNING: Please DO NOT pass a partition_key of non-string type to the send_batch method." + "The Event Hub service ignores partition_key of non-string type, " + "in which case events will be assigned to all partitions using round-robin.") + if isinstance(event_data_batch, EventDataBatch): if partition_id or partition_key: raise TypeError("partition_id and partition_key should be None when sending an EventDataBatch " @@ -306,6 +312,11 @@ def create_batch(self, **kwargs): partition_id = kwargs.get("partition_id", None) partition_key = kwargs.get("partition_key", None) + if partition_key and not isinstance(partition_key, str): + _LOGGER.info("WARNING: Please DO NOT pass a partition_key of non-string type to the create_batch method." + "The Event Hub service ignores partition_key of non-string type, " + "in which case events will be assigned to all partitions using round-robin.") + if max_size_in_bytes and max_size_in_bytes > self._max_message_size_on_link: raise ValueError( "Max message size: {} is too large, acceptable max batch size is: {} bytes.".format( diff --git a/sdk/eventhub/azure-eventhub/azure/eventhub/aio/_producer_client_async.py b/sdk/eventhub/azure-eventhub/azure/eventhub/aio/_producer_client_async.py index 6caa8e9f5144..fea849c05279 100644 --- a/sdk/eventhub/azure-eventhub/azure/eventhub/aio/_producer_client_async.py +++ b/sdk/eventhub/azure-eventhub/azure/eventhub/aio/_producer_client_async.py @@ -277,6 +277,12 @@ async def send_batch( """ partition_id = kwargs.get("partition_id") partition_key = kwargs.get("partition_key") + + if partition_key and not isinstance(partition_key, str): + _LOGGER.info("WARNING: Please DO NOT pass a partition_key of non-string type to the send_batch method." + "The Event Hub service ignores partition_key of non-string type, " + "in which case events will be assigned to all partitions using round-robin.") + if isinstance(event_data_batch, EventDataBatch): if partition_id or partition_key: raise TypeError("partition_id and partition_key should be None when sending an EventDataBatch " @@ -337,6 +343,11 @@ async def create_batch( if not self._max_message_size_on_link: await self._get_max_mesage_size() + if partition_key and not isinstance(partition_key, str): + _LOGGER.info("WARNING: Please DO NOT pass a partition_key of non-string type to the create_batch method." + "The Event Hub service ignores partition_key of non-string type, " + "in which case events will be assigned to all partitions using round-robin.") + if max_size_in_bytes and max_size_in_bytes > self._max_message_size_on_link: raise ValueError( "Max message size: {} is too large, acceptable max batch size is: {} bytes.".format( From 0e3ae8457708026f9fc52aabc9dabf7adbbcedf8 Mon Sep 17 00:00:00 2001 From: "Adam Ling (MSFT)" Date: Thu, 4 Mar 2021 07:57:04 -0800 Subject: [PATCH 2/3] move the logging info into eventdatabatch to avoid duplicate logging when sending list, also updated the wording --- .../azure-eventhub/azure/eventhub/_common.py | 9 ++++++++ .../azure/eventhub/_producer_client.py | 23 ++++++++----------- .../eventhub/aio/_producer_client_async.py | 23 ++++++++----------- 3 files changed, 27 insertions(+), 28 deletions(-) diff --git a/sdk/eventhub/azure-eventhub/azure/eventhub/_common.py b/sdk/eventhub/azure-eventhub/azure/eventhub/_common.py index d15196dd8cf3..7f7f967ac63f 100644 --- a/sdk/eventhub/azure-eventhub/azure/eventhub/_common.py +++ b/sdk/eventhub/azure-eventhub/azure/eventhub/_common.py @@ -350,6 +350,15 @@ class EventDataBatch(object): def __init__(self, max_size_in_bytes=None, partition_id=None, partition_key=None): # type: (Optional[int], Optional[str], Optional[Union[str, bytes]]) -> None + + if partition_key and not isinstance(partition_key, (six.text_type, six.binary_type)): + _LOGGER.info( + "WARNING: Setting partition_key of non-string value on the events to be sent is discouraged " + "as the partition_key will be ignored by the Event Hub service and events will be assigned " + "to all partitions using round-robin. Furthermore, there are SDKs for consuming events which expect " + "partition_key to only be string type, they might fail to parse the non-string value." + ) + self.max_size_in_bytes = max_size_in_bytes or constants.MAX_MESSAGE_LENGTH_BYTES self.message = BatchMessage(data=[], multi_messages=False, properties=None) self._partition_id = partition_id diff --git a/sdk/eventhub/azure-eventhub/azure/eventhub/_producer_client.py b/sdk/eventhub/azure-eventhub/azure/eventhub/_producer_client.py index 4b0a0960d437..1e199d9674e7 100644 --- a/sdk/eventhub/azure-eventhub/azure/eventhub/_producer_client.py +++ b/sdk/eventhub/azure-eventhub/azure/eventhub/_producer_client.py @@ -4,6 +4,7 @@ # -------------------------------------------------------------------------------------------- import logging import threading +import six from typing import Any, Union, TYPE_CHECKING, Dict, List, Optional, cast @@ -222,8 +223,10 @@ def send_batch(self, event_data_batch, **kwargs): A `TypeError` will be raised if partition_key is specified and event_data_batch is an `EventDataBatch` because `EventDataBatch` itself has partition_key. If both partition_id and partition_key are provided, the partition_id will take precedence. - **WARNING: Please DO NOT pass a partition_key of non-string type. The Event Hub service ignores partition_key - of non-string type, in which case events will be assigned to all partitions using round-robin.** + **WARNING: Setting partition_key of non-string value on the events to be sent is discouraged + as the partition_key will be ignored by the Event Hub service and events will be assigned + to all partitions using round-robin. Furthermore, there are SDKs for consuming events which expect + partition_key to only be string type, they might fail to parse the non-string value.** :rtype: None :raises: :class:`AuthenticationError` :class:`ConnectError` @@ -247,11 +250,6 @@ def send_batch(self, event_data_batch, **kwargs): partition_id = kwargs.get("partition_id") partition_key = kwargs.get("partition_key") - if partition_key and not isinstance(partition_key, str): - _LOGGER.info("WARNING: Please DO NOT pass a partition_key of non-string type to the send_batch method." - "The Event Hub service ignores partition_key of non-string type, " - "in which case events will be assigned to all partitions using round-robin.") - if isinstance(event_data_batch, EventDataBatch): if partition_id or partition_key: raise TypeError("partition_id and partition_key should be None when sending an EventDataBatch " @@ -289,8 +287,10 @@ def create_batch(self, **kwargs): :keyword str partition_key: With the given partition_key, event data will be sent to a particular partition of the Event Hub decided by the service. If both partition_id and partition_key are provided, the partition_id will take precedence. - **WARNING: Please DO NOT pass a partition_key of non-string type. The Event Hub service ignores partition_key - of non-string type, in which case events will be assigned to all partitions using round-robin.** + **WARNING: Setting partition_key of non-string value on the events to be sent is discouraged + as the partition_key will be ignored by the Event Hub service and events will be assigned + to all partitions using round-robin. Furthermore, there are SDKs for consuming events which expect + partition_key to only be string type, they might fail to parse the non-string value.** :keyword int max_size_in_bytes: The maximum size of bytes data that an EventDataBatch object can hold. By default, the value is determined by your Event Hubs tier. :rtype: ~azure.eventhub.EventDataBatch @@ -312,11 +312,6 @@ def create_batch(self, **kwargs): partition_id = kwargs.get("partition_id", None) partition_key = kwargs.get("partition_key", None) - if partition_key and not isinstance(partition_key, str): - _LOGGER.info("WARNING: Please DO NOT pass a partition_key of non-string type to the create_batch method." - "The Event Hub service ignores partition_key of non-string type, " - "in which case events will be assigned to all partitions using round-robin.") - if max_size_in_bytes and max_size_in_bytes > self._max_message_size_on_link: raise ValueError( "Max message size: {} is too large, acceptable max batch size is: {} bytes.".format( diff --git a/sdk/eventhub/azure-eventhub/azure/eventhub/aio/_producer_client_async.py b/sdk/eventhub/azure-eventhub/azure/eventhub/aio/_producer_client_async.py index fea849c05279..ed0178e05202 100644 --- a/sdk/eventhub/azure-eventhub/azure/eventhub/aio/_producer_client_async.py +++ b/sdk/eventhub/azure-eventhub/azure/eventhub/aio/_producer_client_async.py @@ -4,6 +4,7 @@ # -------------------------------------------------------------------------------------------- import asyncio import logging +import six from typing import Any, Union, TYPE_CHECKING, List, Optional, Dict, cast from uamqp import constants @@ -253,8 +254,10 @@ async def send_batch( A `TypeError` will be raised if partition_key is specified and event_data_batch is an `EventDataBatch` because `EventDataBatch` itself has partition_key. If both partition_id and partition_key are provided, the partition_id will take precedence. - **WARNING: Please DO NOT pass a partition_key of non-string type. The Event Hub service ignores partition_key - of non-string type, in which case events will be assigned to all partitions using round-robin.** + **WARNING: Setting partition_key of non-string value on the events to be sent is discouraged + as the partition_key will be ignored by the Event Hub service and events will be assigned + to all partitions using round-robin. Furthermore, there are SDKs for consuming events which expect + partition_key to only be string type, they might fail to parse the non-string value.** :rtype: None :raises: :class:`AuthenticationError` :class:`ConnectError` @@ -278,11 +281,6 @@ async def send_batch( partition_id = kwargs.get("partition_id") partition_key = kwargs.get("partition_key") - if partition_key and not isinstance(partition_key, str): - _LOGGER.info("WARNING: Please DO NOT pass a partition_key of non-string type to the send_batch method." - "The Event Hub service ignores partition_key of non-string type, " - "in which case events will be assigned to all partitions using round-robin.") - if isinstance(event_data_batch, EventDataBatch): if partition_id or partition_key: raise TypeError("partition_id and partition_key should be None when sending an EventDataBatch " @@ -324,8 +322,10 @@ async def create_batch( :param str partition_key: With the given partition_key, event data will be sent to a particular partition of the Event Hub decided by the service. If both partition_id and partition_key are provided, the partition_id will take precedence. - **WARNING: Please DO NOT pass a partition_key of non-string type. The Event Hub service ignores partition_key - of non-string type, in which case events will be assigned to all partitions using round-robin.** + **WARNING: Setting partition_key of non-string value on the events to be sent is discouraged + as the partition_key will be ignored by the Event Hub service and events will be assigned + to all partitions using round-robin. Furthermore, there are SDKs for consuming events which expect + partition_key to only be string type, they might fail to parse the non-string value.** :param int max_size_in_bytes: The maximum size of bytes data that an EventDataBatch object can hold. By default, the value is determined by your Event Hubs tier. :rtype: ~azure.eventhub.EventDataBatch @@ -343,11 +343,6 @@ async def create_batch( if not self._max_message_size_on_link: await self._get_max_mesage_size() - if partition_key and not isinstance(partition_key, str): - _LOGGER.info("WARNING: Please DO NOT pass a partition_key of non-string type to the create_batch method." - "The Event Hub service ignores partition_key of non-string type, " - "in which case events will be assigned to all partitions using round-robin.") - if max_size_in_bytes and max_size_in_bytes > self._max_message_size_on_link: raise ValueError( "Max message size: {} is too large, acceptable max batch size is: {} bytes.".format( From 3c4fbcc3b057284e58d6364b0a5fea4bc60bd02f Mon Sep 17 00:00:00 2001 From: "Adam Ling (MSFT)" Date: Thu, 4 Mar 2021 07:59:26 -0800 Subject: [PATCH 3/3] remove unused six module --- sdk/eventhub/azure-eventhub/azure/eventhub/_producer_client.py | 1 - .../azure-eventhub/azure/eventhub/aio/_producer_client_async.py | 1 - 2 files changed, 2 deletions(-) diff --git a/sdk/eventhub/azure-eventhub/azure/eventhub/_producer_client.py b/sdk/eventhub/azure-eventhub/azure/eventhub/_producer_client.py index 1e199d9674e7..9ae9dad761e4 100644 --- a/sdk/eventhub/azure-eventhub/azure/eventhub/_producer_client.py +++ b/sdk/eventhub/azure-eventhub/azure/eventhub/_producer_client.py @@ -4,7 +4,6 @@ # -------------------------------------------------------------------------------------------- import logging import threading -import six from typing import Any, Union, TYPE_CHECKING, Dict, List, Optional, cast diff --git a/sdk/eventhub/azure-eventhub/azure/eventhub/aio/_producer_client_async.py b/sdk/eventhub/azure-eventhub/azure/eventhub/aio/_producer_client_async.py index ed0178e05202..7035060a75ff 100644 --- a/sdk/eventhub/azure-eventhub/azure/eventhub/aio/_producer_client_async.py +++ b/sdk/eventhub/azure-eventhub/azure/eventhub/aio/_producer_client_async.py @@ -4,7 +4,6 @@ # -------------------------------------------------------------------------------------------- import asyncio import logging -import six from typing import Any, Union, TYPE_CHECKING, List, Optional, Dict, cast from uamqp import constants