async def send_async(): TOPIC_NAME = config['topic_name'] SERVICE_NAMESPACE = config['service_namespace'] KEY_NAME = config['key_name'] KEY_VALUE = config['key_value'] HOSTNAME = '{}.servicebus.windows.net'.format(SERVICE_NAMESPACE) uri = "sb://{}/{}".format(HOSTNAME, TOPIC_NAME) sas_auth = authentication.SASTokenAsync.from_shared_access_key( uri, KEY_NAME, KEY_VALUE) target = "amqps://{}/{}".format(HOSTNAME, TOPIC_NAME) send_client = uamqp.SendClientAsync(target, auth=sas_auth, debug=False) start_time = time.time() count = 0 time_printed = 0 while True: count += 1 end_time = time.time() period = end_time - start_time if time_printed < int(period): time_printed = int(period) rate = count / (end_time - start_time) print("".join([str(count), " messages in ", str(period), " secs ; rate=" + str(rate) + " msgs/sec"])) msg_content = b"hello world" message = uamqp.Message(msg_content) await send_client.send_message_async(message) await send_client.close_async()
async def test_event_hubs_batch_send_async(live_eventhub_config): for _ in range(10): def data_generator(): for i in range(50): msg_content = "Hello world {}".format(i).encode('utf-8') yield msg_content message_batch = uamqp.message.BatchMessage(data_generator()) uri = "sb://{}/{}".format(live_eventhub_config['hostname'], live_eventhub_config['event_hub']) sas_auth = authentication.SASTokenAsync.from_shared_access_key( uri, live_eventhub_config['key_name'], live_eventhub_config['access_key']) target = "amqps://{}/{}/Partitions/0".format( live_eventhub_config['hostname'], live_eventhub_config['event_hub']) send_client = uamqp.SendClientAsync(target, auth=sas_auth, debug=False) send_client.queue_message(message_batch) results = await send_client.send_all_messages_async() assert not [ m for m in results if m == uamqp.constants.MessageState.SendFailed ]
async def test_event_hubs_send_large_message_after_socket_lost( live_eventhub_config): uri = "sb://{}/{}".format(live_eventhub_config['hostname'], live_eventhub_config['event_hub']) sas_auth = authentication.SASTokenAsync.from_shared_access_key( uri, live_eventhub_config['key_name'], live_eventhub_config['access_key']) target = "amqps://{}/{}".format(live_eventhub_config['hostname'], live_eventhub_config['event_hub']) send_client = uamqp.SendClientAsync(target, auth=sas_auth, debug=True) try: await send_client.open_async() while not await send_client.client_ready_async(): await send_client.do_work_async() # the connection idle timeout setting on the EH service is 240s, after 240s no activity # on the connection, the service would send detach to the client, the underlying socket on the client # is still able to work to receive the frame. # HOWEVER, after no activity on the client socket > 300s, the underlying socket would get completely lost: # the socket reports "Failure: sending socket failed 10054" on windows # or "Failure: sending socket failed. errno=104" on linux which indicates the socket is lost await asyncio.sleep(350) with pytest.raises(uamqp.errors.AMQPConnectionError): await send_client.send_message_async( uamqp.message.Message(b't' * 1024 * 700)) finally: await send_client.close_async()
async def send_async(uri, key_name, key_value, target): sas_auth = authentication.SASTokenAsync.from_shared_access_key( uri, key_name, key_value) send_client = uamqp.SendClientAsync(target, auth=sas_auth, debug=False) while True: msg_content = b"hello world" message = uamqp.Message(msg_content) await send_client.send_message_async(message) await send_client.close_async()
async def test_event_hubs_client_send_async(live_eventhub_config): properties = {b"SendData": b"Property_String_Value_1"} msg_content = b"hello world" message = uamqp.Message(msg_content, application_properties=properties) plain_auth = authentication.SASLPlain(live_eventhub_config['hostname'], live_eventhub_config['key_name'], live_eventhub_config['access_key']) target = "amqps://{}/{}".format(live_eventhub_config['hostname'], live_eventhub_config['event_hub']) send_client = uamqp.SendClientAsync(target, auth=plain_auth, debug=False) send_client.queue_message(message) results = await send_client.send_all_messages_async() assert not [m for m in results if m == uamqp.constants.MessageState.SendFailed]
async def test_event_hubs_send_override_token_refresh_window( live_eventhub_config): uri = "sb://{}/{}".format(live_eventhub_config['hostname'], live_eventhub_config['event_hub']) target = "amqps://{}/{}/Partitions/0".format( live_eventhub_config['hostname'], live_eventhub_config['event_hub']) token = None async def get_token(): nonlocal token return _AccessToken(token, expiry) jwt_auth = authentication.JWTTokenAsync( uri, uri, get_token, refresh_window=300 # set refresh window to be 5 mins ) send_client = uamqp.SendClientAsync(target, auth=jwt_auth, debug=False) # use token of which the valid remaining time < refresh window expiry = int(time.time()) + (60 * 4 + 30) # 4.5 minutes token = utils.create_sas_token(live_eventhub_config['key_name'].encode(), live_eventhub_config['access_key'].encode(), uri.encode(), expiry=timedelta(minutes=4, seconds=30)) for _ in range(3): message = uamqp.message.Message(body='Hello World') await send_client.send_message_async(message) auth_status = constants.CBSAuthStatus(jwt_auth._cbs_auth.get_status()) assert auth_status == constants.CBSAuthStatus.RefreshRequired # update token, the valid remaining time > refresh window expiry = int(time.time()) + (60 * 5 + 30) # 5.5 minutes token = utils.create_sas_token(live_eventhub_config['key_name'].encode(), live_eventhub_config['access_key'].encode(), uri.encode(), expiry=timedelta(minutes=5, seconds=30)) for _ in range(3): message = uamqp.message.Message(body='Hello World') await send_client.send_message_async(message) auth_status = constants.CBSAuthStatus(jwt_auth._cbs_auth.get_status()) assert auth_status == constants.CBSAuthStatus.Ok await send_client.close_async()
async def test_event_hubs_async_sender_sync(live_eventhub_config): annotations={b"x-opt-partition-key": b"PartitionKeyInfo"} msg_content = b"hello world" message = uamqp.Message(msg_content, annotations=annotations) uri = "sb://{}/{}".format(live_eventhub_config['hostname'], live_eventhub_config['event_hub']) sas_auth = authentication.SASTokenAsync.from_shared_access_key(uri, live_eventhub_config['key_name'], live_eventhub_config['access_key']) target = "amqps://{}/{}".format(live_eventhub_config['hostname'], live_eventhub_config['event_hub']) send_client = uamqp.SendClientAsync(target, auth=sas_auth, debug=False) for _ in range(10): message = uamqp.Message(msg_content, application_properties=annotations, annotations=annotations) send_client.send_message(message) send_client.close()
async def test_iot_hub_send_async(live_iothub_config): msg_content = b"hello world" msg_props = uamqp.message.MessageProperties() msg_props.to = '/devices/{}/messages/devicebound'.format(live_iothub_config['device']) msg_props.message_id = str(uuid4()) message = uamqp.Message(msg_content, properties=msg_props) operation = '/messages/devicebound' endpoint = _build_iothub_amqp_endpoint_from_target(live_iothub_config) target = 'amqps://' + endpoint + operation log.info("Target: {}".format(target)) send_client = uamqp.SendClientAsync(target, debug=False) send_client.queue_message(message) results = await send_client.send_all_messages_async() assert not [m for m in results if m == uamqp.constants.MessageState.SendFailed]
async def test_event_hubs_idempotent_producer(live_eventhub_config): uri = "sb://{}/{}".format(live_eventhub_config['hostname'], live_eventhub_config['event_hub']) sas_auth = authentication.SASTokenAsync.from_shared_access_key( uri, live_eventhub_config['key_name'], live_eventhub_config['access_key']) target = "amqps://{}/{}/Partitions/0".format( live_eventhub_config['hostname'], live_eventhub_config['event_hub']) symbol_array = [ uamqp_types.AMQPSymbol(b"com.microsoft:idempotent-producer") ] desired_capabilities = utils.data_factory( uamqp_types.AMQPArray(symbol_array)) link_properties = { uamqp_types.AMQPSymbol(b"com.microsoft:timeout"): uamqp_types.AMQPLong(int(60 * 1000)) } def on_attach(attach_source, attach_target, properties, error): if str(attach_target) == target: on_attach.owner_level = properties.get( b"com.microsoft:producer-epoch") on_attach.producer_group_id = properties.get( b"com.microsoft:producer-id") on_attach.starting_sequence_number = properties.get( b"com.microsoft:producer-sequence-number") send_client = uamqp.SendClientAsync( target, auth=sas_auth, desired_capabilities=desired_capabilities, link_properties=link_properties, on_attach=on_attach, debug=True) await send_client.open_async() while not await send_client.client_ready_async(): await asyncio.sleep(0.05) assert on_attach.owner_level is not None assert on_attach.producer_group_id is not None assert on_attach.starting_sequence_number is not None await send_client.close_async()
async def test_event_hubs_client_send_multiple_async(live_eventhub_config): properties = {b"SendData": b"Property_String_Value_1"} msg_content = b"hello world" plain_auth = authentication.SASLPlain(live_eventhub_config['hostname'], live_eventhub_config['key_name'], live_eventhub_config['access_key']) assert not plain_auth.consumed target = "amqps://{}/{}".format(live_eventhub_config['hostname'], live_eventhub_config['event_hub']) send_client = uamqp.SendClientAsync(target, auth=plain_auth, debug=False) messages = [] for i in range(10): messages.append(uamqp.Message(msg_content, application_properties=properties)) send_client.queue_message(*messages) assert len(send_client.pending_messages) == 10 results = await send_client.send_all_messages_async() assert len(results) == 10 assert not [m for m in results if m == uamqp.constants.MessageState.SendFailed] assert plain_auth.consumed assert send_client.pending_messages == []
async def test_event_hubs_send_timeout_async(live_eventhub_config): async def _hack_client_run(cls): """MessageSender Link is now open - perform message send on all pending messages. Will return True if operation successful and client can remain open for further work. :rtype: bool """ # pylint: disable=protected-access await asyncio.sleep(6) await cls.message_handler.work_async() cls._waiting_messages = 0 cls._pending_messages = cls._filter_pending() if cls._backoff and not cls._waiting_messages: log.info("Client told to backoff - sleeping for %r seconds", cls._backoff) await cls._connection.sleep_async(cls._backoff) cls._backoff = 0 await cls._connection.work_async() return True uri = "sb://{}/{}".format(live_eventhub_config['hostname'], live_eventhub_config['event_hub']) sas_auth = authentication.SASTokenAsync.from_shared_access_key( uri, live_eventhub_config['key_name'], live_eventhub_config['access_key']) target = "amqps://{}/{}/Partitions/0".format( live_eventhub_config['hostname'], live_eventhub_config['event_hub']) send_client = uamqp.SendClientAsync(target, auth=sas_auth, debug=False, msg_timeout=5000) send_client._client_run_async = types.MethodType(_hack_client_run, send_client) await send_client.open_async() with pytest.raises(uamqp.errors.ClientMessageError): await send_client.send_message_async( uamqp.message.Message(body='Hello World')) await send_client.close_async()
async def event_hubs_send_different_amqp_body_type_async(live_eventhub_config): uri = "sb://{}/{}".format(live_eventhub_config['hostname'], live_eventhub_config['event_hub']) sas_auth = authentication.SASTokenAsync.from_shared_access_key( uri, live_eventhub_config['key_name'], live_eventhub_config['access_key']) target = "amqps://{}/{}/Partitions/0".format( live_eventhub_config['hostname'], live_eventhub_config['event_hub']) send_client = uamqp.SendClientAsync(target, auth=sas_auth, debug=False) data_body_1 = [b'data1', b'data2'] data_body_message_1 = uamqp.message.Message(body=data_body_1) data_body_message_1.application_properties = {'body_type': 'data_body_1'} send_client.queue_message(data_body_message_1) data_body_2 = b'data1' data_body_message_2 = uamqp.message.Message(body=data_body_2, body_type=MessageBodyType.Data) data_body_message_2.application_properties = {'body_type': 'data_body_2'} send_client.queue_message(data_body_message_2) value_body_1 = [ b'data1', -1.23, True, { b'key': b'value' }, [1, False, 1.23, b'4'] ] value_body_message_1 = uamqp.message.Message(body=value_body_1) value_body_message_1.application_properties = {'body_type': 'value_body_1'} send_client.queue_message(value_body_message_1) value_body_2 = { b'key1': { b'sub_key': b'sub_value' }, b'key2': b'value', 3: -1.23 } value_body_message_2 = uamqp.message.Message( body=value_body_2, body_type=MessageBodyType.Value) value_body_message_2.application_properties = {'body_type': 'value_body_2'} send_client.queue_message(value_body_message_2) sequence_body_1 = [ b'data1', -1.23, True, { b'key': b'value' }, [b'a', 1.23, True] ] sequence_body_message_1 = uamqp.message.Message( body=sequence_body_1, body_type=MessageBodyType.Sequence) sequence_body_message_1.application_properties = { 'body_type': 'sequence_body_1' } send_client.queue_message(sequence_body_message_1) sequence_body_2 = [[1, 2, 3], [b'aa', b'bb', b'cc'], [True, False, True], [{ b'key1': b'value' }, { b'key2': 123 }]] sequence_body_message_2 = uamqp.message.Message( body=sequence_body_2, body_type=MessageBodyType.Sequence) sequence_body_message_2.application_properties = { 'body_type': 'sequence_body_2' } send_client.queue_message(sequence_body_message_2) results = await send_client.send_all_messages_async(close_on_done=False) assert not [ m for m in results if m == uamqp.constants.MessageState.SendFailed ] sas_auth = authentication.SASTokenAsync.from_shared_access_key( uri, live_eventhub_config['key_name'], live_eventhub_config['access_key']) source = "amqps://{}/{}/ConsumerGroups/{}/Partitions/{}".format( live_eventhub_config['hostname'], live_eventhub_config['event_hub'], live_eventhub_config['consumer_group'], 0) result_dic = {} receive_client = uamqp.ReceiveClientAsync(source, auth=sas_auth, timeout=5000, debug=False, prefetch=10) gen = receive_client.receive_messages_iter_async() async for message in gen: if message.application_properties and message.application_properties.get( b'body_type'): if message.application_properties.get( b'body_type') == b'data_body_1': check_list = [data for data in message.get_data()] assert isinstance(message._body, DataBody) assert check_list == data_body_1 result_dic['data_body_1'] = 1 elif message.application_properties.get( b'body_type') == b'data_body_2': check_list = [data for data in message.get_data()] assert isinstance(message._body, DataBody) assert check_list == [data_body_2] result_dic['data_body_2'] = 1 elif message.application_properties.get( b'body_type') == b'value_body_1': assert message.get_data() == value_body_1 assert isinstance(message._body, ValueBody) result_dic['value_body_1'] = 1 elif message.application_properties.get( b'body_type') == b'value_body_2': assert message.get_data() == value_body_2 assert isinstance(message._body, ValueBody) result_dic['value_body_2'] = 1 elif message.application_properties.get( b'body_type') == b'sequence_body_1': check_list = [data for data in message.get_data()] assert check_list == [sequence_body_1] assert isinstance(message._body, SequenceBody) result_dic['sequence_body_1'] = 1 elif message.application_properties.get( b'body_type') == b'sequence_body_2': check_list = [data for data in message.get_data()] assert check_list == sequence_body_2 assert isinstance(message._body, SequenceBody) result_dic['sequence_body_2'] = 1 log.info(message.annotations.get(b'x-opt-sequence-number')) log.info(str(message)) await send_client.close_async() await receive_client.close_async() assert len(results) == 6