async def test_client_credential_async(self, servicebus_queue, servicebus_namespace, servicebus_namespace_key_name, servicebus_namespace_primary_key, servicebus_namespace_connection_string, **kwargs): # This should "just work" to validate known-good. credential = ServiceBusSharedKeyCredential(servicebus_namespace_key_name, servicebus_namespace_primary_key) hostname = "{}.servicebus.windows.net".format(servicebus_namespace.name) client = ServiceBusClient(hostname, credential) async with client: assert len(client._handlers) == 0 async with client.get_queue_sender(servicebus_queue.name) as sender: await sender.send_messages(ServiceBusMessage("foo")) hostname = "sb://{}.servicebus.windows.net".format(servicebus_namespace.name) client = ServiceBusClient(hostname, credential) async with client: assert len(client._handlers) == 0 async with client.get_queue_sender(servicebus_queue.name) as sender: await sender.send_messages(ServiceBusMessage("foo")) hostname = "https://{}.servicebus.windows.net \ ".format(servicebus_namespace.name) client = ServiceBusClient(hostname, credential) async with client: assert len(client._handlers) == 0 async with client.get_queue_sender(servicebus_queue.name) as sender: await sender.send_messages(ServiceBusMessage("foo"))
async def test_client_named_key_credential_async(self, servicebus_queue, servicebus_namespace, servicebus_namespace_key_name, servicebus_namespace_primary_key, servicebus_namespace_connection_string, **kwargs): hostname = "{}.servicebus.windows.net".format(servicebus_namespace.name) credential = AzureNamedKeyCredential(servicebus_namespace_key_name, servicebus_namespace_primary_key) client = ServiceBusClient(hostname, credential) async with client: async with client.get_queue_sender(servicebus_queue.name) as sender: await sender.send_messages(ServiceBusMessage("foo")) credential.update("foo", "bar") with pytest.raises(Exception): async with client: async with client.get_queue_sender(servicebus_queue.name) as sender: await sender.send_messages(ServiceBusMessage("foo")) # update back to the right key again credential.update(servicebus_namespace_key_name, servicebus_namespace_primary_key) async with client: async with client.get_queue_sender(servicebus_queue.name) as sender: await sender.send_messages(ServiceBusMessage("foo"))
def test_subscription_by_sas_token_credential_conn_str_send_basic( self, servicebus_namespace, servicebus_namespace_key_name, servicebus_namespace_primary_key, servicebus_topic, servicebus_subscription, **kwargs): fully_qualified_namespace = servicebus_namespace.name + '.servicebus.windows.net' with ServiceBusClient( fully_qualified_namespace=fully_qualified_namespace, credential=ServiceBusSharedKeyCredential( policy=servicebus_namespace_key_name, key=servicebus_namespace_primary_key), logging_enable=False) as sb_client: with sb_client.get_topic_sender( topic_name=servicebus_topic.name) as sender: message = ServiceBusMessage(b"Sample topic message") sender.send_messages(message) with sb_client.get_subscription_receiver( topic_name=servicebus_topic.name, subscription_name=servicebus_subscription.name, max_wait_time=5) as receiver: count = 0 for message in receiver: count += 1 message.complete() assert count == 1
async def test_sb_client_incorrect_queue_conn_str_async( self, servicebus_queue_authorization_rule_connection_string, servicebus_queue, wrong_queue, **kwargs): client = ServiceBusClient.from_connection_string( servicebus_queue_authorization_rule_connection_string) async with client: # Validate that the wrong sender/receiver queues with the right credentials fail. with pytest.raises(ValueError): async with client.get_queue_sender(wrong_queue.name) as sender: await sender.send_messages(ServiceBusMessage("test")) with pytest.raises(ValueError): async with client.get_queue_receiver( wrong_queue.name) as receiver: messages = await receiver.receive_messages( max_message_count=1, max_wait_time=1) # But that the correct ones work. async with client.get_queue_sender( servicebus_queue.name) as sender: await sender.send_messages(ServiceBusMessage("test")) async with client.get_queue_receiver( servicebus_queue.name) as receiver: messages = await receiver.receive_messages(max_message_count=1, max_wait_time=1) # Now do the same but with direct connstr initialization. with pytest.raises(ValueError): async with ServiceBusSender._from_connection_string( servicebus_queue_authorization_rule_connection_string, queue_name=wrong_queue.name, ) as sender: await sender.send_messages(ServiceBusMessage("test")) with pytest.raises(ValueError): async with ServiceBusReceiver._from_connection_string( servicebus_queue_authorization_rule_connection_string, queue_name=wrong_queue.name, ) as receiver: messages = await receiver.receive_messages( max_message_count=1, max_wait_time=1) async with ServiceBusSender._from_connection_string( servicebus_queue_authorization_rule_connection_string, queue_name=servicebus_queue.name, ) as sender: await sender.send_messages(ServiceBusMessage("test")) async with ServiceBusReceiver._from_connection_string( servicebus_queue_authorization_rule_connection_string, queue_name=servicebus_queue.name, ) as receiver: messages = await receiver.receive_messages(max_message_count=1, max_wait_time=1)
async def run_async(self): batch = await self.async_sender.create_message_batch() for i in range(self.args.num_messages): try: batch.add_message(ServiceBusMessage(self.data)) except ValueError: # Batch full await self.async_sender.send_messages(batch) batch = await self.async_sender.create_message_batch() batch.add_message(ServiceBusMessage(self.data)) await self.async_sender.send_messages(batch)
def _construct_message(self): if self.send_batch_size != None: batch = ServiceBusMessageBatch() for _ in range(self.send_batch_size): message = ServiceBusMessage(self.pre_process_message_body("a" * self.message_size)) self.pre_process_message(message) batch.add_message(message) self.PreProcessMessageBatch(batch) return batch else: message = ServiceBusMessage(self.pre_process_message_body("a" * self.message_size)) self.pre_process_message(message) return message
async def example_send_and_receive_async(): servicebus_sender = await example_create_servicebus_sender_async() servicebus_receiver = await example_create_servicebus_receiver_async() from azure.servicebus import ServiceBusMessage # [START send_async] async with servicebus_sender: message = ServiceBusMessage("Hello World") await servicebus_sender.send_messages(message) # [END send_async] # [START create_batch_async] async with servicebus_sender: batch_message = await servicebus_sender.create_message_batch() batch_message.add_message( ServiceBusMessage("Single message inside batch")) # [END create_batch_async] # [START peek_messages_async] async with servicebus_receiver: messages = await servicebus_receiver.peek_messages() for message in messages: print(str(message)) # [END peek_messages_async] # [START receive_async] async with servicebus_receiver: messages = await servicebus_receiver.receive_messages(max_wait_time=5) for message in messages: print(str(message)) await message.complete() # [END receive_async] # [START receive_forever_async] async with servicebus_receiver: async for message in servicebus_receiver.get_streaming_message_iter(): print(str(message)) await message.complete() # [END receive_forever_async] # [START auto_lock_renew_message_async] from azure.servicebus.aio import AutoLockRenewer lock_renewal = AutoLockRenewer() async with servicebus_receiver: async for message in servicebus_receiver: lock_renewal.register(message, timeout=60) await process_message(message) await message.complete()
async def _preload_queue(self): data = get_random_bytes(self.args.message_size) async with self.async_service_client.get_queue_sender( self.queue_name) as sender: batch = await sender.create_message_batch() for i in range(self.args.preload): try: batch.add_message(ServiceBusMessage(data)) except ValueError: # Batch full await sender.send_messages(batch) print("Loaded {} messages".format(i)) batch = await sender.create_message_batch() batch.add_message(ServiceBusMessage(data)) await sender.send_messages(batch)
def test_sending_list_of_messages(self): with self.servicebus_client: sender = self.servicebus_client.get_queue_sender( queue_name=QUEUE_NAME) with sender: messages = [ServiceBusMessage("{}") for _ in range(5)] sender.send_messages(messages)
def test_sending_single_message(self): with self.servicebus_client: sender = self.servicebus_client.get_queue_sender( queue_name=QUEUE_NAME) with sender: message = ServiceBusMessage("{}") sender.send_messages(message)
class ServiceBusNotificationService(BaseNotificationService): """Implement the notification service for the service bus service.""" def __init__(self, client): """Initialize the service.""" self._client = client async def async_send_message(self, message, **kwargs): """Send a message.""" dto = {ATTR_ASB_MESSAGE: message} if ATTR_TITLE in kwargs: dto[ATTR_ASB_TITLE] = kwargs[ATTR_TITLE] if ATTR_TARGET in kwargs: dto[ATTR_ASB_TARGET] = kwargs[ATTR_TARGET] if data := kwargs.get(ATTR_DATA): dto.update(data) queue_message = ServiceBusMessage(json.dumps(dto), content_type=CONTENT_TYPE_JSON) try: await self._client.send_messages(queue_message) except ServiceBusError as err: _LOGGER.error( "Could not send service bus notification to %s. %s", self._client.name, err, )
async def renew_lock_on_session_of_the_sessionful_entity(): servicebus_client = ServiceBusClient.from_connection_string(conn_str=CONNECTION_STR) async with servicebus_client: async with servicebus_client.get_queue_sender(queue_name=SESSION_QUEUE_NAME) as sender: msgs_to_send = [ServiceBusMessage("session message: {}".format(i), session_id='SESSION') for i in range(10)] await sender.send_messages(msgs_to_send) print('Send messages to sessionful queue.') renewer = AutoLockRenewer() async with servicebus_client.get_queue_receiver( queue_name=SESSION_QUEUE_NAME, session_id='SESSION', prefetch_count=10 ) as receiver: # automatically renew the lock on the session for 100 seconds renewer.register(receiver.session, timeout=100) print('Register session into AutoLockRenewer.') received_msgs = await receiver.receive_messages(max_message_count=10, max_wait_time=5) await asyncio.sleep(100) # message handling for long period (E.g. application logic) for msg in received_msgs: await msg.complete() print('Complete messages.')
async def renew_lock_on_message_received_from_non_sessionful_entity(): servicebus_client = ServiceBusClient.from_connection_string(conn_str=CONNECTION_STR) async with servicebus_client: async with servicebus_client.get_queue_sender(queue_name=QUEUE_NAME) as sender: msgs_to_send = [ServiceBusMessage("session message: {}".format(i)) for i in range(10)] await sender.send_messages(msgs_to_send) print('Send messages to non-sessionful queue.') # Can also be called via "with AutoLockRenewer() as renewer" to automate shutdown. renewer = AutoLockRenewer() async with servicebus_client.get_queue_receiver(queue_name=QUEUE_NAME, prefetch_count=10) as receiver: received_msgs = await receiver.receive_messages(max_message_count=10, max_wait_time=5) for msg in received_msgs: # automatically renew the lock on each message for 100 seconds renewer.register(msg, timeout=100) print('Register messages into AutoLockRenewer done.') await asyncio.sleep(100) # message handling for long period (E.g. application logic) for msg in received_msgs: await msg.complete() print('Complete messages.') await renewer.close()
def test_subscription_by_servicebus_client_receive_batch_with_deadletter(self, servicebus_namespace_connection_string, servicebus_topic, servicebus_subscription, **kwargs): with ServiceBusClient.from_connection_string( servicebus_namespace_connection_string, logging_enable=False ) as sb_client: with sb_client.get_subscription_receiver( topic_name=servicebus_topic.name, subscription_name=servicebus_subscription.name, max_wait_time=5, receive_mode=ServiceBusReceiveMode.PEEK_LOCK, prefetch_count=10 ) as receiver: with sb_client.get_topic_sender(servicebus_topic.name) as sender: for i in range(10): message = ServiceBusMessage("Dead lettered message no. {}".format(i)) sender.send_messages(message) count = 0 messages = receiver.receive_messages() while messages: for message in messages: print_message(_logger, message) count += 1 receiver.dead_letter_message(message, reason="Testing reason", error_description="Testing description") messages = receiver.receive_messages() assert count == 10 with sb_client.get_subscription_receiver( topic_name=servicebus_topic.name, subscription_name=servicebus_subscription.name, max_wait_time=5, receive_mode=ServiceBusReceiveMode.PEEK_LOCK ) as receiver: count = 0 for message in receiver: print_message(_logger, message) receiver.complete_message(message) count += 1 assert count == 0 with sb_client.get_subscription_receiver( topic_name=servicebus_topic.name, subscription_name=servicebus_subscription.name, sub_queue = ServiceBusSubQueue.DEAD_LETTER, max_wait_time=5, receive_mode=ServiceBusReceiveMode.PEEK_LOCK ) as dl_receiver: count = 0 for message in dl_receiver: dl_receiver.complete_message(message) count += 1 assert message.dead_letter_reason == 'Testing reason' assert message.dead_letter_error_description == 'Testing description' assert message.application_properties[b'DeadLetterReason'] == b'Testing reason' assert message.application_properties[b'DeadLetterErrorDescription'] == b'Testing description' assert count == 10
async def test_subscription_by_subscription_client_conn_str_receive_basic( self, servicebus_namespace_connection_string, servicebus_topic, servicebus_subscription, **kwargs): async with ServiceBusClient.from_connection_string( servicebus_namespace_connection_string, logging_enable=False) as sb_client: async with sb_client.get_topic_sender( topic_name=servicebus_topic.name) as sender: message = ServiceBusMessage(b"Sample topic message") await sender.send_messages(message) with pytest.raises(ValueError): sb_client.get_subscription_receiver( topic_name=servicebus_topic.name, subscription_name=servicebus_subscription.name, max_wait_time=0) async with sb_client.get_subscription_receiver( topic_name=servicebus_topic.name, subscription_name=servicebus_subscription.name, max_wait_time=5) as receiver: with pytest.raises(ValueError): await receiver.receive_messages(max_wait_time=-1) with pytest.raises(ValueError): await receiver.get_streaming_message_iter(max_wait_time=0) count = 0 async for message in receiver: count += 1 await receiver.complete_message(message) assert count == 1
def sample_session_send_receive_with_pool(connection_string, queue_name): concurrent_receivers = 5 sessions = [str(uuid.uuid4()) for i in range(2 * concurrent_receivers)] with ServiceBusClient.from_connection_string(connection_string) as client: with client.get_queue_sender(queue_name) as sender: for session_id in sessions: for i in range(20): message = ServiceBusMessage( "Sample message no. {}".format(i), session_id=session_id) sender.send_messages(message) all_messages = [] futures = [] with concurrent.futures.ThreadPoolExecutor( max_workers=concurrent_receivers) as thread_pool: for _ in range(concurrent_receivers): futures.append( thread_pool.submit(message_processing, client, queue_name, all_messages)) concurrent.futures.wait(futures) print("Received total {} messages across {} sessions.".format( len(all_messages), len(sessions)))
def send_message( self, queue_name: str, messages: Union[str, List[str]], batch_message_flag: bool = False ): """ By using ServiceBusClient Send message(s) to a Service Bus Queue. By using batch_message_flag it enables and send message as batch message :param queue_name: The name of the queue or a QueueProperties with name. :param messages: Message which needs to be sent to the queue. It can be string or list of string. :param batch_message_flag: bool flag, can be set to True if message needs to be sent as batch message. """ if queue_name is None: raise TypeError("Queue name cannot be None.") if not messages: raise ValueError("Messages list cannot be empty.") with self.get_conn() as service_bus_client, service_bus_client.get_queue_sender( queue_name=queue_name ) as sender: with sender: if isinstance(messages, str): if not batch_message_flag: msg = ServiceBusMessage(messages) sender.send_messages(msg) else: self.send_batch_message(sender, [messages]) else: if not batch_message_flag: self.send_list_messages(sender, messages) else: self.send_batch_message(sender, messages)
def send_batch_messages(sender): batch_message = sender.create_message_batch() for i in range(10): try: message = ServiceBusMessage("Data {}".format(i)) except TypeError: # Message body is of an inappropriate type, must be string, bytes or None. continue try: batch_message.add_message(message) except MessageSizeExceededError: # ServiceBusMessageBatch object reaches max_size. # New ServiceBusMessageBatch object can be created here to send more data. # This must be handled at the application layer, by breaking up or condensing. continue last_error = None for _ in range(3): # Send retries try: sender.send_messages(batch_message) return except OperationTimeoutError: # send has timed out, retry. continue except MessageSizeExceededError: # The body provided in the message to be sent is too large. # This must be handled at the application layer, by breaking up or condensing. raise except ServiceBusError as e: # Other types of service bus errors that can be handled at the higher level, such as connection/auth errors # If it happens persistently, should bubble up, and should be logged/alerted if high volume. last_error = e continue if last_error: raise last_error
def send_list(self, message_list): ''' This method will put one message on the queue for each entry in message_list. ''' messages = [ServiceBusMessage(m) for m in message_list] with SenderManager(self.namespace_name, self.queue_name) as sender: sender.send_messages(messages)
def fix_deadletters(servicebus_client): sender = servicebus_client.get_queue_sender(queue_name=QUEUE_NAME) receiver = servicebus_client.get_queue_receiver(queue_name=QUEUE_NAME) dlq_receiver = servicebus_client.get_queue_receiver( queue_name=QUEUE_NAME, sub_queue=ServiceBusSubQueue.DEAD_LETTER) msgs_to_send = [] with dlq_receiver: received_dlq_msgs = dlq_receiver.receive_messages(max_message_count=10, max_wait_time=5) for msg in received_dlq_msgs: if msg.subject and msg.subject == "Bad": msg_copy = ServiceBusMessage(str(msg), subject="Good") msgs_to_send.append(msg_copy) print("Fixing message: Body={}, Subject={}".format( next(msg.body), msg.subject)) dlq_receiver.complete_message(msg) with sender: print("Resending fixed messages") sender.send_messages(msgs_to_send) with receiver: received_msgs = receiver.receive_messages(max_message_count=10, max_wait_time=5) for msg in received_msgs: if msg.subject and msg.subject == "Good": print("Received fixed message: Body={}, Subject={}".format( next(msg.body), msg.subject)) receiver.complete_message(msg)
def _put(self, queue: str, message, **kwargs) -> None: """Put message onto queue.""" queue = self.entity_name(self.queue_name_prefix + queue) msg = ServiceBusMessage(dumps(message)) queue_obj = self._get_asb_sender(queue) queue_obj.sender.send_messages(msg)
async def main(): servicebus_client = ServiceBusClient.from_connection_string( conn_str=CONNECTION_STR) async with servicebus_client: sender = servicebus_client.get_queue_sender(queue_name=QUEUE_NAME) messages = [ ServiceBusMessage("Message to be deferred") for _ in range(10) ] async with sender: await sender.send_messages(messages) receiver = servicebus_client.get_queue_receiver(queue_name=QUEUE_NAME) async with receiver: received_msgs = await receiver.receive_messages( max_message_count=10, max_wait_time=5) deferred_sequenced_numbers = [] for msg in received_msgs: print("Deferring msg: {}".format(str(msg))) deferred_sequenced_numbers.append(msg.sequence_number) await receiver.defer_message(msg) if deferred_sequenced_numbers: received_deferred_msg = await receiver.receive_deferred_messages( sequence_numbers=deferred_sequenced_numbers) for msg in received_deferred_msg: print("Completing deferred msg: {}".format(str(msg))) await receiver.complete_message(msg) else: print("No messages received.")
async def main(): servicebus_client = ServiceBusClient.from_connection_string( conn_str=CONNECTION_STR) async with servicebus_client: sender = servicebus_client.get_queue_sender(queue_name=QUEUE_NAME) messages = [ ServiceBusMessage("Message to be deadlettered") for _ in range(10) ] async with sender: await sender.send_messages(messages) print('dead lettering messages') receiver = servicebus_client.get_queue_receiver(queue_name=QUEUE_NAME) async with receiver: received_msgs = await receiver.receive_messages( max_message_count=10, max_wait_time=5) for msg in received_msgs: print(str(msg)) await receiver.dead_letter_message(msg) print('receiving deadlettered messages') dlq_receiver = servicebus_client.get_queue_receiver( queue_name=QUEUE_NAME, sub_queue=ServiceBusSubQueue.DEAD_LETTER, prefetch_count=10) async with dlq_receiver: received_msgs = await dlq_receiver.receive_messages( max_message_count=10, max_wait_time=5) for msg in received_msgs: print(str(msg)) await dlq_receiver.complete_message(msg)
def example_receive_deadletter_sync(): from azure.servicebus import SubQueue servicebus_connection_str = os.environ['SERVICE_BUS_CONNECTION_STR'] queue_name = os.environ['SERVICE_BUS_QUEUE_NAME'] with ServiceBusClient.from_connection_string( conn_str=servicebus_connection_str) as servicebus_client: with servicebus_client.get_queue_sender( queue_name) as servicebus_sender: servicebus_sender.send_messages(ServiceBusMessage("Hello World")) # [START receive_deadletter_sync] with servicebus_client.get_queue_receiver( queue_name) as servicebus_receiver: messages = servicebus_receiver.receive_messages(max_wait_time=5) for message in messages: servicebus_receiver.dead_letter_message( message, reason='reason for dead lettering', error_description='description for dead lettering') with servicebus_client.get_queue_receiver( queue_name, sub_queue=SubQueue.DeadLetter ) as servicebus_deadletter_receiver: messages = servicebus_deadletter_receiver.receive_messages( max_wait_time=5) for message in messages: servicebus_deadletter_receiver.complete_message(message)
async def schedule_single_message(sender): message = ServiceBusMessage("ServiceBusMessage to be scheduled") scheduled_time_utc = datetime.datetime.utcnow() + datetime.timedelta( seconds=30) sequence_number = await sender.schedule_messages(message, scheduled_time_utc) return sequence_number
def send_message(self, msg): with self.client.get_queue_sender(queue_name) as sender: sender.send_messages( ServiceBusMessage(f"{msg} send on {datetime.now()}")) print("Send message is done.") print(f"sender thread {threading.current_thread()}" ) # send message using the main thread
def get_lemma_messages( lemmas: Iterable[str]) -> Iterable[ServiceBusMessage]: for l in lemmas: yield ServiceBusMessage( l.lower(), message_id=str.format("{}-{}", correlation_id, l), application_properties=application_properties, subject="lemma")
def send_message(message): message = ServiceBusMessage(message) with servicebus_client: sender = servicebus_client.get_queue_sender( queue_name=SERVICEBUS_SEND_QUEUE) with sender: sender.send_messages(message) print("Send: " + str(message))
def test_servicebus_message_repr_with_props(): message = ServiceBusMessage(body="hello", application_properties={'prop': 'test'}, session_id="id_session", message_id="id_message", scheduled_enqueue_time_utc=datetime.now(), time_to_live=timedelta(seconds=30), content_type="content type", correlation_id="correlation", subject="github", partition_key="id_session", to="forward to", reply_to="reply to", reply_to_session_id="reply to session") assert "application_properties={'prop': 'test'}, session_id=id_session," in message.__repr__( ) assert "content_type=content type, correlation_id=correlation, to=forward to, reply_to=reply to, reply_to_session_id=reply to session, subject=github, time_to_live=0:00:30, partition_key=id_session, scheduled_enqueue_time_utc" in message.__repr__( )
async def test_sb_client_bad_credentials_async(self, servicebus_namespace, servicebus_queue, **kwargs): client = ServiceBusClient( fully_qualified_namespace=servicebus_namespace.name + '.servicebus.windows.net', credential=ServiceBusSharedKeyCredential('invalid', 'invalid'), logging_enable=False) async with client: with pytest.raises(ServiceBusAuthenticationError): async with client.get_queue_sender(servicebus_queue.name) as sender: await sender.send_messages(ServiceBusMessage("test"))