async def _handle_exception(self, exception): if isinstance(exception, (errors.LinkDetach, errors.ConnectionClose)): if exception.action and exception.action.retry and self.auto_reconnect: _log.info("Async handler detached. Attempting reconnect.") await self.reconnect() elif exception.condition == constants.ErrorCodes.UnauthorizedAccess: _log.info("Async handler detached. Shutting down.") error = ServiceBusAuthorizationError(str(exception), exception) await self.close(exception=error) raise error else: _log.info("Async handler detached. Shutting down.") error = ServiceBusConnectionError(str(exception), exception) await self.close(exception=error) raise error elif isinstance(exception, errors.MessageHandlerError): if self.auto_reconnect: _log.info("Async handler error. Attempting reconnect.") await self.reconnect() else: _log.info("Async handler error. Shutting down.") error = ServiceBusConnectionError(str(exception), exception) await self.close(exception=error) raise error elif isinstance(exception, errors.AMQPConnectionError): message = "Failed to open handler: {}".format(exception) raise ServiceBusConnectionError(message, exception) else: _log.info("Unexpected error occurred (%r). Shutting down.", exception) error = ServiceBusError("Handler failed: {}".format(exception), exception) await self.close(exception=error) raise error
def delete_subscription(self, topic_name, subscription_name, fail_not_exist=False): """Delete a subscription entity. :param topic_name: The name of the topic where the subscription is. :type topic_name: str :param subscription_name: The name of the subscription to delete. :type subscription_name: str :param fail_not_exist: Whether to raise an exception if the named subscription or topic is not found. If set to True, a ServiceBusResourceNotFound will be raised. Default value is False. :type fail_not_exist: bool :raises: ~azure.servicebus.common.errors.ServiceBusConnectionError if the namesapce is not found. :raises: ~azure.servicebus.common.errors.ServiceBusResourceNotFound if the entity is not found and `fail_not_exist` is set to True. """ try: return self.mgmt_client.delete_subscription( topic_name, subscription_name, fail_not_exist=fail_not_exist) except requests.exceptions.ConnectionError as e: raise ServiceBusConnectionError( "Namespace: {} not found".format(self.service_namespace), e) except azure.common.AzureMissingResourceHttpError as e: raise ServiceBusResourceNotFound( "Specificed queue does not exist.", e)
def get_topic(self, topic_name): """Get a client for a topic entity. :param topic_name: The name of the topic. :type topic_name: str :rtype: ~azure.servicebus.servicebus_client.TopicClient :raises: ~azure.servicebus.common.errors.ServiceBusConnectionError if the namespace is not found. :raises: ~azure.servicebus.common.errors.ServiceBusResourceNotFound if the topic is not found. Example: .. literalinclude:: ../examples/test_examples.py :start-after: [START get_topic_client] :end-before: [END get_topic_client] :language: python :dedent: 8 :caption: Get the specific topic client from Service Bus client """ try: topic = self.mgmt_client.get_topic(topic_name) except requests.exceptions.ConnectionError as e: raise ServiceBusConnectionError( "Namespace: {} not found".format(self.service_namespace), e) except AzureServiceBusResourceNotFound: raise ServiceBusResourceNotFound( "Specificed topic does not exist.") return TopicClient.from_entity( self._get_host(), topic, shared_access_key_name=self.shared_access_key_name, shared_access_key_value=self.shared_access_key_value, debug=self.debug)
def list_topics(self): """Get a client for all topic entities in the namespace. :rtype: list[~azure.servicebus.servicebus_client.TopicClient] :raises: ~azure.servicebus.common.errors.ServiceBusConnectionError if the namespace is not found. Example: .. literalinclude:: ../examples/test_examples.py :start-after: [START list_topics] :end-before: [END list_topics] :language: python :dedent: 4 :caption: List the topics from Service Bus client """ try: topics = self.mgmt_client.list_topics() except requests.exceptions.ConnectionError as e: raise ServiceBusConnectionError( "Namespace: {} not found".format(self.service_namespace), e) topic_clients = [] for topic in topics: topic_clients.append( TopicClient.from_entity( self._get_host(), topic, shared_access_key_name=self.shared_access_key_name, shared_access_key_value=self.shared_access_key_value, debug=self.debug)) return topic_clients
def get_queue(self, queue_name): """Get a client for a queue entity. :param queue_name: The name of the queue. :type queue_name: str :rtype: ~azure.servicebus.servicebus_client.QueueClient :raises: ~azure.servicebus.common.errors.ServiceBusConnectionError if the namespace is not found. :raises: ~azure.servicebus.common.errors.ServiceBusResourceNotFound if the queue is not found. .. admonition:: Example: .. literalinclude:: ../samples/sync_samples/test_examples.py :start-after: [START get_queue_client] :end-before: [END get_queue_client] :language: python :dedent: 8 :caption: Get the specific queue client from Service Bus client """ try: queue = self.mgmt_client.get_queue(queue_name) except requests.exceptions.ConnectionError as e: raise ServiceBusConnectionError( "Namespace: {} not found".format(self.service_namespace), e) except AzureServiceBusResourceNotFound: raise ServiceBusResourceNotFound( "Specificed queue does not exist.") return QueueClient.from_entity( self._get_host(), queue, shared_access_key_name=self.shared_access_key_name, shared_access_key_value=self.shared_access_key_value, mgmt_client=self.mgmt_client, debug=self.debug)
def list_queues(self): """Get clients for all queue entities in the namespace. :rtype: list[~azure.servicebus.servicebus_client.QueueClient] :raises: ~azure.servicebus.common.errors.ServiceBusConnectionError if the namespace is not found. .. admonition:: Example: .. literalinclude:: ../samples/sync_samples/test_examples.py :start-after: [START list_queues] :end-before: [END list_queues] :language: python :dedent: 4 :caption: List the queues from Service Bus client """ try: queues = self.mgmt_client.list_queues() except requests.exceptions.ConnectionError as e: raise ServiceBusConnectionError( "Namespace: {} not found".format(self.service_namespace), e) queue_clients = [] for queue in queues: queue_clients.append( QueueClient.from_entity( self._get_host(), queue, shared_access_key_name=self.shared_access_key_name, shared_access_key_value=self.shared_access_key_value, mgmt_client=self.mgmt_client, debug=self.debug)) return queue_clients
def list_subscriptions(self, topic_name): """Get an async client for all subscription entities in the topic. :param topic_name: The topic to list subscriptions for. :type topic_name: str :rtype: list[~azure.servicebus.aio.async_client.SubscriptionClient] :raises: ~azure.servicebus.common.errors.ServiceBusConnectionError if the namespace is not found. :raises: ~azure.servicebus.common.errors.ServiceBusResourceNotFound if the topic is not found. """ try: subs = self.mgmt_client.list_subscriptions(topic_name) except requests.exceptions.ConnectionError as e: raise ServiceBusConnectionError( "Namespace: {} not found".format(self.service_namespace), e) except AzureServiceBusResourceNotFound: raise ServiceBusResourceNotFound( "Specificed topic does not exist.") sub_clients = [] for sub in subs: sub_clients.append( SubscriptionClient.from_entity( self._get_host(), topic_name, sub, shared_access_key_name=self.shared_access_key_name, shared_access_key_value=self.shared_access_key_value, loop=self.loop, debug=self.debug)) return sub_clients
def list_subscriptions(self, topic_name): """Get a client for all subscription entities in the topic. :param topic_name: The topic to list subscriptions for. :type topic_name: str :rtype: list[~azure.servicebus.servicebus_client.SubscriptionClient] :raises: ~azure.servicebus.common.errors.ServiceBusConnectionError if the namespace is not found. :raises: ~azure.servicebus.common.errors.ServiceBusResourceNotFound if the topic is not found. .. admonition:: Example: .. literalinclude:: ../samples/sync_samples/test_examples.py :start-after: [START list_subscriptions] :end-before: [END list_subscriptions] :language: python :dedent: 4 :caption: List the subscriptions from Service Bus client """ try: subs = self.mgmt_client.list_subscriptions(topic_name) except requests.exceptions.ConnectionError as e: raise ServiceBusConnectionError("Namespace: {} not found".format(self.service_namespace), e) except AzureServiceBusResourceNotFound: raise ServiceBusResourceNotFound("Specificed topic does not exist.") sub_clients = [] for sub in subs: sub_clients.append(SubscriptionClient.from_entity( self._get_host(), topic_name, sub, shared_access_key_name=self.shared_access_key_name, shared_access_key_value=self.shared_access_key_value, transport_type=self.transport_type, debug=self.debug)) return sub_clients
def get_subscription(self, topic_name, subscription_name): """Get a client for a subscription entity. :param topic_name: The name of the topic. :type topic_name: str :param subscription_name: The name of the subscription. :type subscription_name: str :rtype: ~azure.servicebus.servicebus_client.SubscriptionClient :raises: ~azure.servicebus.common.errors.ServiceBusConnectionError if the namespace is not found. :raises: ~azure.servicebus.common.errors.ServiceBusResourceNotFound if the subscription is not found. .. admonition:: Example: .. literalinclude:: ../samples/sync_samples/test_examples.py :start-after: [START get_subscription_client] :end-before: [END get_subscription_client] :language: python :dedent: 8 :caption: Get the specific subscription client from Service Bus client """ try: subscription = self.mgmt_client.get_subscription(topic_name, subscription_name) except requests.exceptions.ConnectionError as e: raise ServiceBusConnectionError("Namespace: {} not found".format(self.service_namespace), e) except AzureServiceBusResourceNotFound: raise ServiceBusResourceNotFound("Specificed subscription does not exist.") return SubscriptionClient.from_entity( self._get_host(), topic_name, subscription, shared_access_key_name=self.shared_access_key_name, shared_access_key_value=self.shared_access_key_value, transport_type=self.transport_type, debug=self.debug)
def create_subscription( self, topic_name, subscription_name, lock_duration=30, requires_session=None, default_message_time_to_live=None, dead_lettering_on_message_expiration=None, dead_lettering_on_filter_evaluation_exceptions=None, enable_batched_operations=None, max_delivery_count=None): """Create a subscription entity. :param topic_name: The name of the topic under which to create the subscription. :param subscription_name: The name of the new subscription. :type subscription_name: str :param lock_duration: The lock durection in seconds for each message in the subscription. :type lock_duration: int :param requires_session: Whether the subscription will be sessionful, and therefore require all message to have a Session ID and be received by a sessionful receiver. Default value is False. :type requires_session: bool :param default_message_time_to_live: The length of time a message will remain in the subscription before it is either discarded or moved to the dead letter queue. :type default_message_time_to_live: ~datetime.timedelta :param dead_lettering_on_message_expiration: Whether to move expired messages to the dead letter queue. Default value is False. :type dead_lettering_on_message_expiration: bool :param dead_lettering_on_filter_evaluation_exceptions: Whether to move messages that error on filtering into the dead letter queue. Default is False, and the messages will be discarded. :type dead_lettering_on_filter_evaluation_exceptions: bool :param max_delivery_count: The maximum number of times a message will attempt to be delivered before it is moved to the dead letter queue. :type max_delivery_count: int :param enable_batched_operations: :type: enable_batched_operations: bool :raises: ~azure.servicebus.common.errors.ServiceBusConnectionError if the namespace is not found. :raises: ~azure.common.AzureConflictHttpError if a queue of the same name already exists. """ sub_properties = Subscription( lock_duration="PT{}S".format(int(lock_duration)), requires_session=requires_session, default_message_time_to_live=default_message_time_to_live, dead_lettering_on_message_expiration= dead_lettering_on_message_expiration, dead_lettering_on_filter_evaluation_exceptions= dead_lettering_on_filter_evaluation_exceptions, max_delivery_count=max_delivery_count, enable_batched_operations=enable_batched_operations) try: return self.mgmt_client.create_subscription( topic_name, subscription_name, subscription=sub_properties, fail_on_exist=True) except requests.exceptions.ConnectionError as e: raise ServiceBusConnectionError( "Namespace: {} not found".format(self.service_namespace), e)
def create_queue( self, queue_name, lock_duration=30, max_size_in_megabytes=None, requires_duplicate_detection=False, requires_session=False, default_message_time_to_live=None, dead_lettering_on_message_expiration=False, duplicate_detection_history_time_window=None, max_delivery_count=None, enable_batched_operations=None): """Create a queue entity. :param queue_name: The name of the new queue. :type queue_name: str :param lock_duration: The lock durection in seconds for each message in the queue. :type lock_duration: int :param max_size_in_megabytes: The max size to allow the queue to grow to. :type max_size_in_megabytes: int :param requires_duplicate_detection: Whether the queue will require every message with a specified time frame to have a unique ID. Non-unique messages will be discarded. Default value is False. :type requires_duplicate_detection: bool :param requires_session: Whether the queue will be sessionful, and therefore require all message to have a Session ID and be received by a sessionful receiver. Default value is False. :type requires_session: bool :param default_message_time_to_live: The length of time a message will remain in the queue before it is either discarded or moved to the dead letter queue. :type default_message_time_to_live: ~datetime.timedelta :param dead_lettering_on_message_expiration: Whether to move expired messages to the dead letter queue. Default value is False. :type dead_lettering_on_message_expiration: bool :param duplicate_detection_history_time_window: The period within which all incoming messages must have a unique message ID. :type duplicate_detection_history_time_window: ~datetime.timedelta :param max_delivery_count: The maximum number of times a message will attempt to be delivered before it is moved to the dead letter queue. :type max_delivery_count: int :param enable_batched_operations: :type: enable_batched_operations: bool :raises: ~azure.servicebus.common.errors.ServiceBusConnectionError if the namespace is not found. :raises: ~azure.common.AzureConflictHttpError if a queue of the same name already exists. """ queue_properties = Queue( lock_duration="PT{}S".format(int(lock_duration)), max_size_in_megabytes=max_size_in_megabytes, requires_duplicate_detection=requires_duplicate_detection, requires_session=requires_session, default_message_time_to_live=default_message_time_to_live, dead_lettering_on_message_expiration=dead_lettering_on_message_expiration, duplicate_detection_history_time_window=duplicate_detection_history_time_window, max_delivery_count=max_delivery_count, enable_batched_operations=enable_batched_operations) try: return self.mgmt_client.create_queue(queue_name, queue=queue_properties, fail_on_exist=True) except requests.exceptions.ConnectionError as e: raise ServiceBusConnectionError("Namespace: {} not found".format(self.service_namespace), e)
def create_topic(self, topic_name, default_message_time_to_live=None, max_size_in_megabytes=None, requires_duplicate_detection=None, duplicate_detection_history_time_window=None, enable_batched_operations=None): """Create a topic entity. :param topic_name: The name of the new topic. :type topic_name: str :param max_size_in_megabytes: The max size to allow the topic to grow to. :type max_size_in_megabytes: int :param requires_duplicate_detection: Whether the topic will require every message with a specified time frame to have a unique ID. Non-unique messages will be discarded. Default value is False. :type requires_duplicate_detection: bool :param default_message_time_to_live: The length of time a message will remain in the topic before it is either discarded or moved to the dead letter queue. :type default_message_time_to_live: ~datetime.timedelta :param duplicate_detection_history_time_window: The period within which all incoming messages must have a unique message ID. :type duplicate_detection_history_time_window: ~datetime.timedelta :param enable_batched_operations: :type: enable_batched_operations: bool :raises: ~azure.servicebus.common.errors.ServiceBusConnectionError if the namespace is not found. :raises: ~azure.common.AzureConflictHttpError if a topic of the same name already exists. """ topic_properties = Topic( max_size_in_megabytes=max_size_in_megabytes, requires_duplicate_detection=requires_duplicate_detection, default_message_time_to_live=default_message_time_to_live, duplicate_detection_history_time_window= duplicate_detection_history_time_window, enable_batched_operations=enable_batched_operations) try: return self.mgmt_client.create_topic(topic_name, topic=topic_properties, fail_on_exist=True) except requests.exceptions.ConnectionError as e: raise ServiceBusConnectionError( "Namespace: {} not found".format(self.service_namespace), e)
def list_topics(self): """Get an async client for all topic entities in the namespace. :rtype: list[~azure.servicebus.aio.async_client.TopicClient] :raises: ~azure.servicebus.common.errors.ServiceBusConnectionError if the namespace is not found. """ try: topics = self.mgmt_client.list_topics() except requests.exceptions.ConnectionError as e: raise ServiceBusConnectionError( "Namespace: {} not found".format(self.service_namespace), e) topic_clients = [] for topic in topics: topic_clients.append( TopicClient.from_entity( self._get_host(), topic, shared_access_key_name=self.shared_access_key_name, shared_access_key_value=self.shared_access_key_value, loop=self.loop, debug=self.debug)) return topic_clients
def get_properties(self): """Perform an operation to update the properties of the entity. :returns: The properties of the entity as a dictionary. :rtype: dict[str, Any] :raises: ~azure.servicebus.common.errors.ServiceBusResourceNotFound if the entity does not exist. :raises: ~azure.servicebus.common.errors.ServiceBusConnectionError if the endpoint cannot be reached. :raises: ~azure.common.AzureHTTPError if the credentials are invalid. """ try: self.entity = self._get_entity() self.properties = dict(self.entity) if hasattr(self.entity, 'requires_session'): self.requires_session = self.entity.requires_session return self.properties except AzureServiceBusResourceNotFound: raise ServiceBusResourceNotFound("Specificed queue does not exist.") except azure.common.AzureHttpError: self.entity = None self.properties = {} self.requires_session = False except requests.exceptions.ConnectionError as e: raise ServiceBusConnectionError("Namespace not found", e)
def list_queues(self): """Get async clients for all queue entities in the namespace. :rtype: list[~azure.servicebus.aio.async_client.QueueClient] :raises: ~azure.servicebus.common.errors.ServiceBusConnectionError if the namespace is not found. """ try: queues = self.mgmt_client.list_queues() except requests.exceptions.ConnectionError as e: raise ServiceBusConnectionError( "Namespace: {} not found".format(self.service_namespace), e) queue_clients = [] for queue in queues: queue_clients.append( QueueClient.from_entity( self._get_host(), queue, shared_access_key_name=self.shared_access_key_name, shared_access_key_value=self.shared_access_key_value, mgmt_client=self.mgmt_client, loop=self.loop, debug=self.debug)) return queue_clients