def test_verify_n_senders(self): n = 2 addr = self.address() # connection should be ok denied = False try: bs1 = BlockingConnection(addr) except ConnectionException: denied = True self.assertFalse(denied) # assert if connections that should open did not open # n senders OK try: s1 = bs1.create_sender(address="****YES_1of2****") s2 = bs1.create_sender(address="****YES_2of2****") except Exception: denied = True self.assertFalse(denied) # n senders should have worked # receiver n+1 should be denied try: s3 = bs1.create_sender("****NO****") except Exception: denied = True self.assertTrue(denied) # sender n+1 should have failed bs1.close()
def test_message_user_id_proxy_zzz_credit_handled(self): # Test for DISPATCH-519. Make sure the REJECTED messages result # in the client receiving credit. credit_limit = 250 # router issues 250 credits ssl_opts = dict() ssl_opts['ssl-trustfile'] = self.ssl_file('ca-certificate.pem') ssl_opts['ssl-certificate'] = self.ssl_file('client-certificate.pem') ssl_opts['ssl-key'] = self.ssl_file('client-private-key.pem') ssl_opts['ssl-password'] = '******' # create the SSL domain object domain = self.create_ssl_domain(ssl_opts) # Send a message with bad user_id. This message should be rejected. # Connection has user_id 'user13'. addr = self.address(13).replace("amqp", "amqps") blocking_connection = BlockingConnection(addr, ssl_domain=domain) blocking_sender = blocking_connection.create_sender("$management") request = proton.Message() request.user_id = u"bad-user-id" for i in range(0, credit_limit+1): result = Delivery.ACCEPTED try: delivery = blocking_sender.send(request, timeout=10) result = delivery.remote_state except proton.utils.SendException as e: result = e.state except proton.utils.Timeout as e: self.assertTrue(False, "Timed out waiting for send credit") self.assertTrue(result == Delivery.REJECTED, "Router accepted a message with user_id that did not match connection user_id")
def test_custom_annotations_match(self): """ The linkRoute on Routers C and B is set to org.apache. Creates a receiver listening on the address 'org.apache' and a sender that sends to address 'org.apache'. Sends a message with custom annotations to org.apache via router QDR.C and makes sure that the message was successfully routed (using full address matching) and received using pre-created links that were created as a result of specifying addresses in the linkRoute attribute('org.apache.'). Make sure custom annotations arrived as well. """ hello_world_3 = "Hello World_3!" # Connects to listener #2 on QDR.C addr = self.routers[2].addresses[0] blocking_connection = BlockingConnection(addr) # Receive on org.apache blocking_receiver = blocking_connection.create_receiver(address="org.apache") apply_options = AtMostOnce() # Sender to to org.apache blocking_sender = blocking_connection.create_sender(address="org.apache", options=apply_options) msg = Message(body=hello_world_3) annotations = {'custom-annotation': '1/Custom_Annotation'} msg.annotations = annotations # Send a message blocking_sender.send(msg) received_message = blocking_receiver.receive() self.assertEqual(hello_world_3, received_message.body) self.assertEqual(received_message.annotations, annotations) blocking_connection.close()
def test_message_user_id_proxy_bad_name_disallowed(self): ssl_opts = dict() ssl_opts['ssl-trustfile'] = self.ssl_file('ca-certificate.pem') ssl_opts['ssl-certificate'] = self.ssl_file('client-certificate.pem') ssl_opts['ssl-key'] = self.ssl_file('client-private-key.pem') ssl_opts['ssl-password'] = '******' # create the SSL domain object domain = self.create_ssl_domain(ssl_opts) # Send a message with bad user_id. This message should be rejected. # Connection has user_id 'user13'. addr = self.address(13).replace("amqp", "amqps") blocking_connection = BlockingConnection(addr, ssl_domain=domain) blocking_sender = blocking_connection.create_sender("$management") request = proton.Message() request.user_id = u"bad-user-id" result = Delivery.ACCEPTED try: delivery = blocking_sender.send(request, timeout=10) result = delivery.remote_state except proton.utils.SendException as e: result = e.state self.assertTrue (result == Delivery.REJECTED, "Router accepted a message with user_id that did not match connection user_id")
def test_expire_never_sender_disallowed(self): addr = self.routers[1].addresses[0] connection = BlockingConnection(addr) try: sender = connection.create_sender(address="org.apache", options=[SenderExpiry(Terminus.EXPIRE_NEVER)]) self.fail("link should have been detached") except LinkDetached: pass connection.close()
def test_non_zero_timeout_sender_disallowed(self): addr = self.routers[1].addresses[0] connection = BlockingConnection(addr) try: sender = connection.create_sender(address="org.apache", options=[SenderTimeout(10)]) self.fail("link should have been detached") except LinkDetached: pass connection.close()
def test_yy_query_many_links(self): # This test will fail without the fix for DISPATCH-974 c = BlockingConnection(self.address()) count = 0 links = [] COUNT = 5000 ADDRESS_SENDER = "examples-sender" ADDRESS_RECEIVER = "examples-receiver" # This loop creates 5000 consumer and 5000 producer links with # different addresses while True: count += 1 r = c.create_receiver(ADDRESS_RECEIVER + str(count)) links.append(r) s = c.create_sender(ADDRESS_SENDER + str(count)) links.append(c) if count == COUNT: break # Try fetching all 10,000 addresses # This qdmanage query command would fail without the fix # for DISPATCH-974 query_command = 'QUERY --type=org.apache.qpid.dispatch.router.address' outs = json.loads(self.run_qdmanage(query_command)) sender_addresses = 0 receiver_addresses = 0 for out in outs: if ADDRESS_SENDER in out['name']: sender_addresses += 1 if ADDRESS_RECEIVER in out['name']: receiver_addresses += 1 self.assertEqual(sender_addresses, COUNT) self.assertEqual(receiver_addresses, COUNT) query_command = 'QUERY --type=link' outs = json.loads(self.run_qdmanage(query_command)) out_links = 0 in_links = 0 for out in outs: if out.get('owningAddr'): if ADDRESS_SENDER in out['owningAddr']: in_links += 1 if ADDRESS_RECEIVER in out['owningAddr']: out_links += 1 self.assertEqual(out_links, COUNT) self.assertEqual(in_links, COUNT)
def test_aaa_partial_link_route_match(self): """ The linkRoutePattern on Routers C and B is set to org.apache. Creates a receiver listening on the address 'org.apache.dev' and a sender that sends to address 'org.apache.dev'. Sends a message to org.apache.dev via router QDR.C and makes sure that the message was successfully routed (using partial address matching) and received using pre-created links that were created as a result of specifying addresses in the linkRoutePattern attribute('org.apache.'). """ hello_world_1 = "Hello World_1!" # Connects to listener #2 on QDR.C addr = self.routers[2].addresses[1] blocking_connection = BlockingConnection(addr) # Receive on org.apache.dev blocking_receiver = blocking_connection.create_receiver(address="org.apache.dev") apply_options = AtMostOnce() # Sender to to org.apache.dev blocking_sender = blocking_connection.create_sender(address="org.apache.dev", options=apply_options) msg = Message(body=hello_world_1) # Send a message blocking_sender.send(msg) received_message = blocking_receiver.receive() self.assertEqual(hello_world_1, received_message.body) # Connect to the router acting like the broker (QDR.A) and check the deliveriesIngress and deliveriesEgress local_node = Node.connect(self.routers[0].addresses[0], timeout=TIMEOUT) self.assertEqual(u'QDR.A', local_node.query(type='org.apache.qpid.dispatch.router', attribute_names=['routerId']).results[0][0]) self.assertEqual(1, local_node.read(type='org.apache.qpid.dispatch.router.address', name='router.address/M0org.apache.dev').deliveriesEgress, "deliveriesEgress is wrong") self.assertEqual(1, local_node.read(type='org.apache.qpid.dispatch.router.address', name='router.address/M0org.apache.dev').deliveriesIngress, "deliveriesIngress is wrong") # There should be 4 links - # 1. outbound receiver link on org.apache.dev # 2. inbound sender link on blocking_sender # 3. inbound link to the $management # 4. outbound link to $management # self.assertEqual(4, len() self.assertEquals(4, len(local_node.query(type='org.apache.qpid.dispatch.router.link').results)) #blocking_receiver.close() blocking_connection.close()
def test_forwarding_sync(self): """ Forward unsettled messages to multiple subscribers """ config = [ ('router', {'mode': 'standalone', 'id': 'QDR.mcast'}), ('listener', {'role': 'normal', 'host': '0.0.0.0', 'port': self.tester.get_port(), 'saslMechanisms':'ANONYMOUS'}), ('address', {'pattern': 'nextHop2/#', 'distribution': 'multicast'}), ('exchange', {'address': 'Address3', 'name': 'Exchange1', 'alternateAddress': 'altNextHop'}), ('binding', {'name': 'binding1', 'exchangeName': 'Exchange1', 'bindingKey': 'a.b', 'nextHopAddress': 'nextHop1'}), ('binding', {'name': 'binding2', 'exchangeName': 'Exchange1', 'bindingKey': '*.b', 'nextHopAddress': 'nextHop2'}) ] router = self.tester.qdrouterd('QDR.mcast', Qdrouterd.Config(config)) # create clients for message transfer conn = BlockingConnection(router.addresses[0]) sender = conn.create_sender(address="Address3", options=AtLeastOnce()) nhop1 = AsyncTestReceiver(address=router.addresses[0], source="nextHop1") nhop2A = AsyncTestReceiver(address=router.addresses[0], source="nextHop2") nhop2B = AsyncTestReceiver(address=router.addresses[0], source="nextHop2") alt = AsyncTestReceiver(address=router.addresses[0], source="altNextHop") sender.send(Message(subject='a.b', body='A')) sender.send(Message(subject='x.y', body='B')) self.assertEqual('A', nhop1.queue.get(timeout=TIMEOUT).body) self.assertEqual('A', nhop2A.queue.get(timeout=TIMEOUT).body) self.assertEqual('A', nhop2B.queue.get(timeout=TIMEOUT).body) self.assertEqual('B', alt.queue.get(timeout=TIMEOUT).body) nhop1.stop() nhop2A.stop() nhop2B.stop() alt.stop() conn.close() self.assertTrue(nhop1.queue.empty()) self.assertTrue(nhop2A.queue.empty()) self.assertTrue(nhop2B.queue.empty()) self.assertTrue(alt.queue.empty())
def test_large_messages(self): """ Verify that multi-frame messages are forwarded properly """ MAX_FRAME=1024 config = [ ('router', {'mode': 'interior', 'id': 'QDR.X', 'allowUnsettledMulticast': 'yes'}), ('listener', {'port': self.tester.get_port(), 'stripAnnotations': 'no', 'maxFrameSize': MAX_FRAME}), ('address', {'pattern': 'nextHop1/#', 'distribution': 'multicast'}), ('exchange', {'address': 'AddressA', 'name': 'ExchangeA'}), ('binding', {'name': 'bindingA1', 'exchangeName': 'ExchangeA', 'bindingKey': 'a/b', 'nextHopAddress': 'nextHop1'}) ] router = self.tester.qdrouterd('QDR.X', Qdrouterd.Config(config), wait=True) # connect clients to router B (no exchange) nhop1A = AsyncTestReceiver(router.addresses[0], 'nextHop1', conn_args={'max_frame_size': MAX_FRAME}) nhop1B = AsyncTestReceiver(router.addresses[0], 'nextHop1', conn_args={'max_frame_size': MAX_FRAME}) conn = BlockingConnection(router.addresses[0], max_frame_size=MAX_FRAME) sender = conn.create_sender(address="AddressA") jumbo = (10 * MAX_FRAME) * 'X' sender.send(Message(subject='a/b', body=jumbo)) # multicast self.assertEqual(jumbo, nhop1A.queue.get(timeout=TIMEOUT).body) self.assertEqual(jumbo, nhop1B.queue.get(timeout=TIMEOUT).body) nhop1A.stop() nhop1B.stop() conn.close()
def test_forwarding_fanout(self): """ Verify bindings that do not have a key receive all messages """ config = [ ('exchange', {'address': 'AddressF', 'name': 'ExchangeF'}), ('binding', {'name': 'binding1', 'exchangeName': 'ExchangeF', 'bindingKey': 'pattern', 'nextHopAddress': 'nextHop1'}), # two bindings w/o key ('binding', {'name': 'binding2', 'exchangeName': 'ExchangeF', 'nextHopAddress': 'nextHop2'}), ('binding', {'name': 'binding3', 'exchangeName': 'ExchangeF', 'nextHopAddress': 'nextHop3'}) ] for meth in ['amqp', 'mqtt']: config[0][1]['matchMethod'] = meth router = self._create_router('A', config) # create clients for message transfer conn = BlockingConnection(router.addresses[0]) sender = conn.create_sender(address="AddressF", options=AtMostOnce()) nhop1 = conn.create_receiver(address="nextHop1", credit=100) nhop2 = conn.create_receiver(address="nextHop2", credit=100) nhop3 = conn.create_receiver(address="nextHop3", credit=100) # send message with subject "nope" # should arrive at nextHop2 & 3 only sender.send(Message(subject='nope', body='A')) self.assertEqual('A', nhop2.receive(timeout=TIMEOUT).body) self.assertEqual('A', nhop3.receive(timeout=TIMEOUT).body) # send message with subject "pattern" # forwarded to all bindings: sender.send(Message(subject='pattern', body='B')) self.assertEqual('B', nhop1.receive(timeout=TIMEOUT).body) self.assertEqual('B', nhop2.receive(timeout=TIMEOUT).body) self.assertEqual('B', nhop3.receive(timeout=TIMEOUT).body) conn.close() router.teardown()
def test_full_link_route_match(self): """ The linkRoutePattern on Routers C and B is set to org.apache. Creates a receiver listening on the address 'org.apache' and a sender that sends to address 'org.apache'. Sends a message to org.apache via router QDR.C and makes sure that the message was successfully routed (using full address matching) and received using pre-created links that were created as a result of specifying addresses in the linkRoutePattern attribute('org.apache.'). """ hello_world_3 = "Hello World_3!" # Connects to listener #2 on QDR.C addr = self.routers[2].addresses[1] blocking_connection = BlockingConnection(addr) # Receive on org.apache blocking_receiver = blocking_connection.create_receiver(address="org.apache") apply_options = AtMostOnce() # Sender to to org.apache blocking_sender = blocking_connection.create_sender(address="org.apache", options=apply_options) msg = Message(body=hello_world_3) # Send a message blocking_sender.send(msg) received_message = blocking_receiver.receive() self.assertEqual(hello_world_3, received_message.body) local_node = Node.connect(self.routers[0].addresses[0], timeout=TIMEOUT) # Make sure that the router node acting as the broker (QDR.A) had one message routed through it. This confirms # that the message was link routed self.assertEqual(1, local_node.read(type='org.apache.qpid.dispatch.router.address', name='router.address/M0org.apache').deliveriesEgress, "deliveriesEgress is wrong") self.assertEqual(1, local_node.read(type='org.apache.qpid.dispatch.router.address', name='router.address/M0org.apache').deliveriesIngress, "deliveriesIngress is wrong") #blocking_receiver.close() blocking_connection.close()
def test_full_link_route_match_1(self): """ This test is pretty much the same as the previous test (test_full_link_route_match) but the connection is made to router QDR.B instead of QDR.C and we expect the message to be link routed successfully. """ hello_world_4 = "Hello World_4!" addr = self.routers[2].addresses[0] blocking_connection = BlockingConnection(addr) # Receive on org.apache blocking_receiver = blocking_connection.create_receiver(address="org.apache") apply_options = AtMostOnce() # Sender to to org.apache blocking_sender = blocking_connection.create_sender(address="org.apache", options=apply_options) msg = Message(body=hello_world_4) # Send a message blocking_sender.send(msg) received_message = blocking_receiver.receive() self.assertEqual(hello_world_4, received_message.body) local_node = Node.connect(self.routers[0].addresses[0], timeout=TIMEOUT) # Make sure that the router node acting as the broker (QDR.A) had one message routed through it. This confirms # that the message was link routed self.assertEqual(1, local_node.read(type='org.apache.qpid.dispatch.router.address', name='M0org.apache').deliveriesEgress, "deliveriesEgress is wrong") self.assertEqual(1, local_node.read(type='org.apache.qpid.dispatch.router.address', name='M0org.apache').deliveriesIngress, "deliveriesIngress is wrong") blocking_connection.close()
def run(self): try: ssl = SSLDomain(SSLDomain.MODE_CLIENT) ssl.set_credentials(str(self.options.accountPublicKey), str(self.options.accountPrivateKey), str("")) ssl.set_trusted_ca_db(str(self.options.brokerPublicKey)) ssl.set_peer_authentication(SSLDomain.VERIFY_PEER_NAME, trusted_CAs=str(self.options.brokerPublicKey)) connection = BlockingConnection(self.address, ssl_domain=ssl, heartbeat=60000) receiver = connection.create_receiver(self.response_address) sender = connection.create_sender(self.request_address) message = Message(body="<FIXML>...</FIXML>", reply_to=self.reply_adress) print("-I- Sending request message: " + message.body) sender.send(message); try: received_message = receiver.receive(timeout=self.options.timeout) print("-I- Received response message: " + received_message.body) self.message_counter += 1 receiver.accept() except Timeout, e: print("-I- No message received for ", self.options.timeout, " seconds") connection.close()
def test_forwarding_mqtt(self): """ Simple forwarding over a single mqtt exchange """ config = [ ('exchange', { 'address': 'Address2', 'name': 'Exchange1', 'matchMethod': 'mqtt', 'alternateAddress': 'altNextHop' }), ('binding', { 'name': 'binding1', 'exchangeName': 'Exchange1', 'bindingKey': 'a/b', 'nextHopAddress': 'nextHop1' }), ('binding', { 'name': 'binding2', 'exchangeName': 'Exchange1', 'bindingKey': 'a/+', 'nextHopAddress': 'nextHop2' }), ('binding', { 'name': 'binding3', 'exchangeName': 'Exchange1', 'bindingKey': 'c/#', 'nextHopAddress': 'nextHop1' }), ('binding', { 'name': 'binding4', 'exchangeName': 'Exchange1', 'bindingKey': 'c/b', 'nextHopAddress': 'nextHop2' }), ] router = self._create_router('B', config) # create clients for message transfer conn = BlockingConnection(router.addresses[0]) sender = conn.create_sender(address="Address2", options=AtMostOnce()) nhop1 = conn.create_receiver(address="nextHop1", credit=100) nhop2 = conn.create_receiver(address="nextHop2", credit=100) alt = conn.create_receiver(address="altNextHop", credit=100) # send message with subject "a.b" # matches (binding1, binding2) # forwarded to NextHop1, NextHop2 sender.send(Message(subject='a/b', body='A')) self.assertEqual('A', nhop1.receive(timeout=TIMEOUT).body) self.assertEqual('A', nhop2.receive(timeout=TIMEOUT).body) # send message with subject "a/c" # matches binding2 # -> NextHop2 sender.send(Message(subject='a/c', body='B')) self.assertEqual('B', nhop2.receive(timeout=TIMEOUT).body) # send message with subject "c/b" # matches bindings 3,4 # -> NextHop1, NextHop2 sender.send(Message(subject='c/b', body='C')) self.assertEqual('C', nhop1.receive(timeout=TIMEOUT).body) self.assertEqual('C', nhop2.receive(timeout=TIMEOUT).body) # send message with subject "c/b/dee/eee" # matches binding3 # -> NextHop1 sender.send(Message(subject='c/b/dee/eee', body='D')) self.assertEqual('D', nhop1.receive(timeout=TIMEOUT).body) # send message with subject "x.y.z" # no binding match # -> alternate sender.send(Message(subject='x.y.z', body="?")) self.assertEqual('?', alt.receive(timeout=TIMEOUT).body) # ensure there are no more messages on either hop: self.assertRaises(Timeout, nhop1.receive, timeout=0.25) self.assertRaises(Timeout, nhop2.receive, timeout=0.25) self.assertRaises(Timeout, alt.receive, timeout=0.25) # validate counters self._validate_binding(router, name='binding1', matchedCount=1) self._validate_binding(router, name='binding2', matchedCount=2) self._validate_binding(router, name='binding3', matchedCount=2) self._validate_binding(router, name='binding4', matchedCount=1) self._validate_exchange(router, name="Exchange1", receivedCount=5, forwardedCount=5, divertedCount=1, droppedCount=0) conn.close()
def test_forwarding_mqtt(self): """ Simple forwarding over a single mqtt exchange """ config = [ ('exchange', {'address': 'Address2', 'name': 'Exchange1', 'matchMethod': 'mqtt', 'alternateAddress': 'altNextHop'}), ('binding', {'name': 'binding1', 'exchangeName': 'Exchange1', 'bindingKey': 'a/b', 'nextHopAddress': 'nextHop1'}), ('binding', {'name': 'binding2', 'exchangeName': 'Exchange1', 'bindingKey': 'a/+', 'nextHopAddress': 'nextHop2'}), ('binding', {'name': 'binding3', 'exchangeName': 'Exchange1', 'bindingKey': 'c/#', 'nextHopAddress': 'nextHop1'}), ('binding', {'name': 'binding4', 'exchangeName': 'Exchange1', 'bindingKey': 'c/b', 'nextHopAddress': 'nextHop2'}), ] router = self._create_router('B', config) # create clients for message transfer conn = BlockingConnection(router.addresses[0]) sender = conn.create_sender(address="Address2", options=AtMostOnce()) nhop1 = conn.create_receiver(address="nextHop1", credit=100) nhop2 = conn.create_receiver(address="nextHop2", credit=100) alt = conn.create_receiver(address="altNextHop", credit=100) # send message with subject "a.b" # matches (binding1, binding2) # forwarded to NextHop1, NextHop2 sender.send(Message(subject='a/b', body='A')) self.assertEqual('A', nhop1.receive(timeout=TIMEOUT).body) self.assertEqual('A', nhop2.receive(timeout=TIMEOUT).body) # send message with subject "a/c" # matches binding2 # -> NextHop2 sender.send(Message(subject='a/c', body='B')) self.assertEqual('B', nhop2.receive(timeout=TIMEOUT).body) # send message with subject "c/b" # matches bindings 3,4 # -> NextHop1, NextHop2 sender.send(Message(subject='c/b', body='C')) self.assertEqual('C', nhop1.receive(timeout=TIMEOUT).body) self.assertEqual('C', nhop2.receive(timeout=TIMEOUT).body) # send message with subject "c/b/dee/eee" # matches binding3 # -> NextHop1 sender.send(Message(subject='c/b/dee/eee', body='D')) self.assertEqual('D', nhop1.receive(timeout=TIMEOUT).body) # send message with subject "x.y.z" # no binding match # -> alternate sender.send(Message(subject='x.y.z', body="?")) self.assertEqual('?', alt.receive(timeout=TIMEOUT).body) # ensure there are no more messages on either hop: self.assertRaises(Timeout, nhop1.receive, timeout=0.25) self.assertRaises(Timeout, nhop2.receive, timeout=0.25) self.assertRaises(Timeout, alt.receive, timeout=0.25) # validate counters self._validate_binding(router, name='binding1', matchedCount=1) self._validate_binding(router, name='binding2', matchedCount=2) self._validate_binding(router, name='binding3', matchedCount=2) self._validate_binding(router, name='binding4', matchedCount=1) self._validate_exchange(router, name="Exchange1", receivedCount=5, forwardedCount=5, divertedCount=1, droppedCount=0) conn.close()
def test_forwarding(self): """ Simple forwarding over a single 0-10 exchange """ config = [ ('exchange', {'address': 'Address1', 'name': 'Exchange1', 'matchMethod': 'amqp'}), # two different patterns, same next hop: ('binding', {'name': 'binding1', 'exchangeName': 'Exchange1', 'bindingKey': 'a.*', 'nextHopAddress': 'nextHop1'}), ('binding', {'name': 'binding2', 'exchangeName': 'Exchange1', 'bindingKey': 'a.b', 'nextHopAddress': 'nextHop1'}), # duplicate patterns, different next hops: ('binding', {'name': 'binding3', 'exchangeName': 'Exchange1', 'bindingKey': 'a.c.#', 'nextHopAddress': 'nextHop1'}), ('binding', {'name': 'binding4', 'exchangeName': 'Exchange1', 'bindingKey': 'a.c.#', 'nextHopAddress': 'nextHop2'}), # match for nextHop2 only ('binding', {'name': 'binding5', 'exchangeName': 'Exchange1', 'bindingKey': 'a.b.c', 'nextHopAddress': 'nextHop2'}) ] router = self._create_router('A', config) # create clients for message transfer conn = BlockingConnection(router.addresses[0]) sender = conn.create_sender(address="Address1", options=AtMostOnce()) nhop1 = conn.create_receiver(address="nextHop1", credit=100) nhop2 = conn.create_receiver(address="nextHop2", credit=100) # verify initial metrics self._validate_exchange(router, name='Exchange1', bindingCount=5, receivedCount=0, droppedCount=0, forwardedCount=0, divertedCount=0) for b in range(5): self._validate_binding(router, name='binding%s' % (b + 1), matchedCount=0) # send message with subject "a.b" # matches (binding1, binding2) # forwarded to NextHop1 only sender.send(Message(subject='a.b', body='A')) self.assertEqual('A', nhop1.receive(timeout=TIMEOUT).body) # send message with subject "a.c" # matches (bindings 1,3,4) # -> NextHop1, NextHop2 sender.send(Message(subject='a.c', body='B')) self.assertEqual('B', nhop1.receive(timeout=TIMEOUT).body) self.assertEqual('B', nhop2.receive(timeout=TIMEOUT).body) # send message with subject "a.c.d" # matches bindings 3,4 # -> NextHop1, NextHop2 sender.send(Message(subject='a.c.d', body='C')) self.assertEqual('C', nhop1.receive(timeout=TIMEOUT).body) self.assertEqual('C', nhop2.receive(timeout=TIMEOUT).body) # send message with subject "x.y.z" # no binding match - expected to drop # not forwarded sender.send(Message(subject='x.y.z', body=["I am Noone"])) # send message with subject "a.b.c" # matches binding5 # -> NextHop2 sender.send(Message(subject='a.b.c', body='D')) self.assertEqual('D', nhop2.receive(timeout=TIMEOUT).body) # ensure there are no more messages on either hop: self.assertRaises(Timeout, nhop1.receive, timeout=0.25) self.assertRaises(Timeout, nhop2.receive, timeout=0.25) # validate counters self._validate_binding(router, name='binding1', matchedCount=2) self._validate_binding(router, name='binding2', matchedCount=1) self._validate_binding(router, name='binding3', matchedCount=2) self._validate_binding(router, name='binding4', matchedCount=2) self._validate_binding(router, name='binding5', matchedCount=1) self._validate_exchange(router, name="Exchange1", receivedCount=5, forwardedCount=4, divertedCount=0, droppedCount=1) conn.close()
def test_forwarding_sync(self): """ Forward unsettled messages to multiple subscribers """ config = [('router', { 'mode': 'standalone', 'id': 'QDR.mcast' }), ('listener', { 'role': 'normal', 'host': '0.0.0.0', 'port': self.tester.get_port(), 'saslMechanisms': 'ANONYMOUS' }), ('address', { 'pattern': 'nextHop2/#', 'distribution': 'multicast' }), ('exchange', { 'address': 'Address3', 'name': 'Exchange1', 'alternateAddress': 'altNextHop' }), ('binding', { 'name': 'binding1', 'exchangeName': 'Exchange1', 'bindingKey': 'a.b', 'nextHopAddress': 'nextHop1' }), ('binding', { 'name': 'binding2', 'exchangeName': 'Exchange1', 'bindingKey': '*.b', 'nextHopAddress': 'nextHop2' })] router = self.tester.qdrouterd('QDR.mcast', Qdrouterd.Config(config)) # create clients for message transfer conn = BlockingConnection(router.addresses[0]) sender = conn.create_sender(address="Address3", options=AtLeastOnce()) nhop1 = AsyncTestReceiver(address=router.addresses[0], source="nextHop1") nhop2A = AsyncTestReceiver(address=router.addresses[0], source="nextHop2") nhop2B = AsyncTestReceiver(address=router.addresses[0], source="nextHop2") alt = AsyncTestReceiver(address=router.addresses[0], source="altNextHop") sender.send(Message(subject='a.b', body='A')) sender.send(Message(subject='x.y', body='B')) self.assertEqual('A', nhop1.queue.get(timeout=TIMEOUT).body) self.assertEqual('A', nhop2A.queue.get(timeout=TIMEOUT).body) self.assertEqual('A', nhop2B.queue.get(timeout=TIMEOUT).body) self.assertEqual('B', alt.queue.get(timeout=TIMEOUT).body) nhop1.stop() nhop2A.stop() nhop2B.stop() alt.stop() conn.close() self.assertTrue(nhop1.queue.empty()) self.assertTrue(nhop2A.queue.empty()) self.assertTrue(nhop2B.queue.empty()) self.assertTrue(alt.queue.empty())
class Connection(BaseConnection): """ Proton connection. """ __metaclass__ = ThreadSingleton @staticmethod def ssl_domain(connector): """ Get the ssl domain using the broker settings. :param connector: A broker. :type connector: Connector :return: The populated domain. :rtype: SSLDomain :raise: SSLException :raise: ValueError """ domain = None if connector.use_ssl(): connector.ssl.validate() domain = SSLDomain(SSLDomain.MODE_CLIENT) domain.set_trusted_ca_db(connector.ssl.ca_certificate) domain.set_credentials( connector.ssl.client_certificate, connector.ssl.client_key or connector.ssl.client_certificate, None) if connector.ssl.host_validation: mode = SSLDomain.VERIFY_PEER_NAME else: mode = SSLDomain.VERIFY_PEER domain.set_peer_authentication(mode) return domain def __init__(self, url): """ :param url: The connector url. :type url: str """ super(Connection, self).__init__(url) self._impl = None def is_open(self): """ Get whether the connection has been opened. :return: True if open. :rtype bool """ return self._impl is not None @retry(ConnectionException, SSLException) def open(self): """ Open a connection to the broker. """ if self.is_open(): # already open return connector = Connector.find(self.url) domain = self.ssl_domain(connector) log.info('open: %s', connector) self._impl = BlockingConnection( connector.url.canonical, heartbeat=connector.heartbeat, ssl_domain=domain) log.info('opened: %s', self.url) def sender(self, address): """ Get a message sender for the specified address. :param address: An AMQP address. :type address: str :return: A sender. :rtype: proton.utils.BlockingSender """ name = utf8(uuid4()) return self._impl.create_sender(address, name=name) def receiver(self, address=None, dynamic=False): """ Get a message receiver for the specified address. :param address: An AMQP address. :type address: str :param dynamic: Indicates link address is dynamically assigned. :type dynamic: bool :return: A receiver. :rtype: proton.utils.BlockingReceiver """ options = None name = utf8(uuid4()) if dynamic: # needed by dispatch router options = DynamicNodeProperties({'x-opt-qd.address': unicode(address)}) address = None return self._impl.create_receiver(address, name=name, dynamic=dynamic, options=options) def close(self): """ Close the connection. """ connection = self._impl self._impl = None try: connection.close() log.info('closed: %s', self.url) except Exception, pe: log.debug(utf8(pe))
def test_remote_exchange(self): """ Verify that the exchange and bindings are visible to other routers in the network """ def router(self, name, extra_config): config = [('router', { 'mode': 'interior', 'id': 'QDR.%s' % name, 'allowUnsettledMulticast': 'yes' }), ('listener', { 'port': self.tester.get_port(), 'stripAnnotations': 'no' })] + extra_config config = Qdrouterd.Config(config) self.routers.append(self.tester.qdrouterd(name, config, wait=True)) self.inter_router_port = self.tester.get_port() self.routers = [] router(self, 'A', [('listener', { 'role': 'inter-router', 'port': self.inter_router_port }), ('address', { 'pattern': 'nextHop1/#', 'distribution': 'multicast' }), ('address', { 'pattern': 'nextHop2/#', 'distribution': 'balanced' }), ('address', { 'pattern': 'nextHop3/#', 'distribution': 'closest' }), ('exchange', { 'address': 'AddressA', 'name': 'ExchangeA', 'matchMethod': 'mqtt' }), ('binding', { 'name': 'bindingA1', 'exchangeName': 'ExchangeA', 'bindingKey': 'a/b', 'nextHopAddress': 'nextHop1' }), ('binding', { 'name': 'bindingA2', 'exchangeName': 'ExchangeA', 'bindingKey': 'a/+', 'nextHopAddress': 'nextHop2' }), ('binding', { 'name': 'bindingA3', 'exchangeName': 'ExchangeA', 'bindingKey': '+/b', 'nextHopAddress': 'nextHop3' }), ('binding', { 'name': 'bindingA4', 'exchangeName': 'ExchangeA', 'bindingKey': 'a/#', 'nextHopAddress': 'NotSubscribed' })]) router(self, 'B', [('connector', { 'name': 'connectorToA', 'role': 'inter-router', 'port': self.inter_router_port, 'verifyHostname': 'no' }), ('address', { 'pattern': 'nextHop1/#', 'distribution': 'multicast' }), ('address', { 'pattern': 'nextHop2/#', 'distribution': 'balanced' }), ('address', { 'pattern': 'nextHop3/#', 'distribution': 'closest' })]) self.routers[0].wait_router_connected('QDR.B') self.routers[1].wait_router_connected('QDR.A') self.routers[1].wait_address('AddressA') # connect clients to router B (no exchange) nhop1A = AsyncTestReceiver(self.routers[1].addresses[0], 'nextHop1') nhop1B = AsyncTestReceiver(self.routers[1].addresses[0], 'nextHop1') nhop2 = AsyncTestReceiver(self.routers[1].addresses[0], 'nextHop2') nhop3 = AsyncTestReceiver(self.routers[1].addresses[0], 'nextHop3') self.routers[0].wait_address('nextHop1', remotes=1) self.routers[0].wait_address('nextHop2', remotes=1) self.routers[0].wait_address('nextHop3', remotes=1) conn = BlockingConnection(self.routers[1].addresses[0]) sender = conn.create_sender(address="AddressA", options=AtLeastOnce()) sender.send(Message(subject='a/b', body='Hi!')) # multicast self.assertEqual('Hi!', nhop1A.queue.get(timeout=TIMEOUT).body) self.assertEqual('Hi!', nhop1B.queue.get(timeout=TIMEOUT).body) # balanced and closest self.assertEqual('Hi!', nhop2.queue.get(timeout=TIMEOUT).body) self.assertEqual('Hi!', nhop3.queue.get(timeout=TIMEOUT).body) nhop1A.stop() nhop1B.stop() nhop2.stop() nhop3.stop() conn.close()
def test_ddd_partial_link_route_match(self): """ The linkRoute on Routers C and B is set to org.apache. Creates a receiver listening on the address 'org.apache.dev' and a sender that sends to address 'org.apache.dev'. Sends a message to org.apache.dev via router QDR.C and makes sure that the message was successfully routed (using partial address matching) and received using pre-created links that were created as a result of specifying addresses in the linkRoute attribute('org.apache.'). """ hello_world_1 = "Hello World_1!" # Connects to listener #2 on QDR.C addr = self.routers[2].addresses[0] blocking_connection = BlockingConnection(addr) # Receive on org.apache.dev blocking_receiver = blocking_connection.create_receiver( address="org.apache.dev") apply_options = AtMostOnce() # Sender to org.apache.dev blocking_sender = blocking_connection.create_sender( address="org.apache.dev", options=apply_options) msg = Message(body=hello_world_1) # Send a message blocking_sender.send(msg) received_message = blocking_receiver.receive() self.assertEqual(hello_world_1, received_message.body) # Connect to the router acting like the broker (QDR.A) and check the deliveriesIngress and deliveriesEgress local_node = Node.connect(self.routers[0].addresses[0], timeout=TIMEOUT) self.assertEqual( u'QDR.A', local_node.query(type='org.apache.qpid.dispatch.router', attribute_names=[u'id']).results[0][0]) self.assertEqual( 1, local_node.read(type='org.apache.qpid.dispatch.router.address', name='M0org.apache.dev').deliveriesEgress) self.assertEqual( 1, local_node.read(type='org.apache.qpid.dispatch.router.address', name='M0org.apache.dev').deliveriesIngress) # There should be 4 links - # 1. outbound receiver link on org.apache.dev # 2. inbound sender link on blocking_sender # 3. inbound link to the $management # 4. outbound link to $management # self.assertEqual(4, len() self.assertEquals( 4, len( local_node.query( type='org.apache.qpid.dispatch.router.link').results)) blocking_connection.close()
def test_multiple_log_file(self): blocking_connection = BlockingConnection(self.address) TEST_ADDRESS = "test_multiple_log_file" blocking_receiver = blocking_connection.create_receiver( address=TEST_ADDRESS) blocking_sender = blocking_connection.create_sender( address=TEST_ADDRESS, options=apply_options) TEST_MSG = "LOGTEST" msg = Message(body=TEST_MSG) blocking_sender.send(msg) received_message = blocking_receiver.receive() self.assertEqual(TEST_MSG, received_message.body) server_log_found = True all_server_logs = True try: with open(self.router.outdir + '/test-router-server.log', 'r') as server_log: for line in server_log: parts = line.split(" ") if (parts[3] != "SERVER"): all_server_logs = False break except: server_log_found = False self.assertTrue(all_server_logs) self.assertTrue(server_log_found) protocol_log_found = True all_protocol_logs = True try: with open(self.router.outdir + '/test-router-protocol.log', 'r') as protocol_log: for line in protocol_log: parts = line.split(" ") if (parts[3] != "PROTOCOL"): all_protocol_logs = False break except: protocol_log_found = False self.assertTrue(protocol_log_found) self.assertTrue(all_protocol_logs) core_router_log_found = True all_core_router_logs = True try: with open(self.router.outdir + '/test-router-core.log', 'r') as core_log: for line in core_log: parts = line.split(" ") if parts[3] != "ROUTER_CORE" and parts[3] != "ROUTER": all_core_router_logs = False break except: core_router_log_found = False self.assertTrue(core_router_log_found) self.assertTrue(all_core_router_logs)
def test_normal_sender_allowed(self): addr = self.routers[1].addresses[0] connection = BlockingConnection(addr) sender = connection.create_sender(address="org.apache") connection.close()
def test_yy_query_many_links(self): # This test will fail without the fix for DISPATCH-974 c = BlockingConnection(self.router.addresses[0]) count = 0 links = [] COUNT = 5000 ADDRESS_SENDER = "examples-sender" ADDRESS_RECEIVER = "examples-receiver" # This loop creates 5000 consumer and 5000 producer links while True: count += 1 r = c.create_receiver(ADDRESS_RECEIVER + str(count)) links.append(r) s = c.create_sender(ADDRESS_SENDER + str(count)) links.append(c) if count == COUNT: break # Now we run qdstat command and check if we got back details # about all the 10000 links # We do not specify the limit which means unlimited # which means get everything that is there. outs = self.run_qdstat(['--links']) out_list = outs.split("\n") out_links = 0 in_links = 0 for out in out_list: if "endpoint in" in out and ADDRESS_SENDER in out: in_links += 1 if "endpoint out" in out and ADDRESS_RECEIVER in out: out_links += 1 self.assertEqual(in_links, COUNT) self.assertEqual(out_links, COUNT) # Run qdstat with a limit more than 10,000 outs = self.run_qdstat(['--links', '--limit=15000']) out_list = outs.split("\n") out_links = 0 in_links = 0 for out in out_list: if "endpoint in" in out and ADDRESS_SENDER in out: in_links += 1 if "endpoint out" in out and ADDRESS_RECEIVER in out: out_links += 1 self.assertEqual(in_links, COUNT) self.assertEqual(out_links, COUNT) # Run qdstat with a limit less than 10,000 outs = self.run_qdstat(['--links', '--limit=2000']) out_list = outs.split("\n") links = 0 for out in out_list: if "endpoint" in out and "examples" in out: links += 1 self.assertEqual(links, 2000) # Run qdstat with a limit of 700 because 700 # is the maximum number of rows we get per request outs = self.run_qdstat(['--links', '--limit=700']) out_list = outs.split("\n") links = 0 for out in out_list: if "endpoint" in out and "examples" in out: links += 1 self.assertEqual(links, 700) # Run qdstat with a limit of 500 because 700 # is the maximum number of rows we get per request # and we want to try something less than 700 outs = self.run_qdstat(['--links', '--limit=500']) out_list = outs.split("\n") links = 0 for out in out_list: if "endpoint" in out and "examples" in out: links += 1 self.assertEqual(links, 500) # This test would fail without the fix for DISPATCH-974 outs = self.run_qdstat(['--address']) out_list = outs.split("\n") sender_addresses = 0 receiver_addresses = 0 for out in out_list: if ADDRESS_SENDER in out: sender_addresses += 1 if ADDRESS_RECEIVER in out: receiver_addresses += 1 self.assertEqual(sender_addresses, COUNT) self.assertEqual(receiver_addresses, COUNT) c.close()
# distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # from __future__ import print_function from proton import Message from proton.utils import BlockingConnection from proton.handlers import IncomingMessageHandler conn = BlockingConnection("localhost:5672") receiver = conn.create_receiver("examples") sender = conn.create_sender("examples") sender.send(Message(body="Hello World!")); msg = receiver.receive(timeout=30) print(msg.body) receiver.accept() conn.close()
def test_remote_exchange(self): """ Verify that the exchange and bindings are visible to other routers in the network """ def router(self, name, extra_config): config = [ ('router', {'mode': 'interior', 'id': 'QDR.%s'%name, 'allowUnsettledMulticast': 'yes'}), ('listener', {'port': self.tester.get_port(), 'stripAnnotations': 'no'}) ] + extra_config config = Qdrouterd.Config(config) self.routers.append(self.tester.qdrouterd(name, config, wait=True)) self.inter_router_port = self.tester.get_port() self.routers = [] router(self, 'A', [('listener', {'role': 'inter-router', 'port': self.inter_router_port}), ('address', {'pattern': 'nextHop1/#', 'distribution': 'multicast'}), ('address', {'pattern': 'nextHop2/#', 'distribution': 'balanced'}), ('address', {'pattern': 'nextHop3/#', 'distribution': 'closest'}), ('exchange', {'address': 'AddressA', 'name': 'ExchangeA', 'matchMethod': 'mqtt'}), ('binding', {'name': 'bindingA1', 'exchangeName': 'ExchangeA', 'bindingKey': 'a/b', 'nextHopAddress': 'nextHop1'}), ('binding', {'name': 'bindingA2', 'exchangeName': 'ExchangeA', 'bindingKey': 'a/+', 'nextHopAddress': 'nextHop2'}), ('binding', {'name': 'bindingA3', 'exchangeName': 'ExchangeA', 'bindingKey': '+/b', 'nextHopAddress': 'nextHop3'}), ('binding', {'name': 'bindingA4', 'exchangeName': 'ExchangeA', 'bindingKey': 'a/#', 'nextHopAddress': 'NotSubscribed'}) ]) router(self, 'B', [('connector', {'name': 'connectorToA', 'role': 'inter-router', 'port': self.inter_router_port, 'verifyHostname': 'no'}), ('address', {'pattern': 'nextHop1/#', 'distribution': 'multicast'}), ('address', {'pattern': 'nextHop2/#', 'distribution': 'balanced'}), ('address', {'pattern': 'nextHop3/#', 'distribution': 'closest'}) ]) self.routers[0].wait_router_connected('QDR.B') self.routers[1].wait_router_connected('QDR.A') self.routers[1].wait_address('AddressA') # connect clients to router B (no exchange) nhop1A = AsyncTestReceiver(self.routers[1].addresses[0], 'nextHop1') nhop1B = AsyncTestReceiver(self.routers[1].addresses[0], 'nextHop1') nhop2 = AsyncTestReceiver(self.routers[1].addresses[0], 'nextHop2') nhop3 = AsyncTestReceiver(self.routers[1].addresses[0], 'nextHop3') self.routers[0].wait_address('nextHop1', remotes=1) self.routers[0].wait_address('nextHop2', remotes=1) self.routers[0].wait_address('nextHop3', remotes=1) conn = BlockingConnection(self.routers[1].addresses[0]) sender = conn.create_sender(address="AddressA", options=AtLeastOnce()) sender.send(Message(subject='a/b', body='Hi!')) # multicast self.assertEqual('Hi!', nhop1A.queue.get(timeout=TIMEOUT).body) self.assertEqual('Hi!', nhop1B.queue.get(timeout=TIMEOUT).body) # balanced and closest self.assertEqual('Hi!', nhop2.queue.get(timeout=TIMEOUT).body) self.assertEqual('Hi!', nhop3.queue.get(timeout=TIMEOUT).body) nhop1A.stop() nhop1B.stop() nhop2.stop() nhop3.stop() conn.close()
def test_zzz_qdmanage_delete_link_route(self): """ We are deleting the link route using qdmanage short name. This should be the last test to run """ # First delete linkRoutes on QDR.B local_node = Node.connect(self.routers[1].addresses[0], timeout=TIMEOUT) result_list = local_node.query(type='org.apache.qpid.dispatch.router.config.linkRoute').results identity_1 = result_list[0][1] identity_2 = result_list[1][1] identity_3 = result_list[2][1] identity_4 = result_list[3][1] cmd = 'DELETE --type=linkRoute --identity=' + identity_1 self.run_qdmanage(cmd=cmd, address=self.routers[1].addresses[0]) cmd = 'DELETE --type=linkRoute --identity=' + identity_2 self.run_qdmanage(cmd=cmd, address=self.routers[1].addresses[0]) cmd = 'DELETE --type=linkRoute --identity=' + identity_3 self.run_qdmanage(cmd=cmd, address=self.routers[1].addresses[0]) cmd = 'DELETE --type=linkRoute --identity=' + identity_4 self.run_qdmanage(cmd=cmd, address=self.routers[1].addresses[0]) cmd = 'QUERY --type=linkRoute' out = self.run_qdmanage(cmd=cmd, address=self.routers[1].addresses[0]) self.assertEquals(out.rstrip(), '[]') # linkRoutes now gone on QDR.B but remember that it still exist on QDR.C # We will now try to create a receiver on address org.apache.dev on QDR.C. # Since the linkRoute on QDR.B is gone, QDR.C # will not allow a receiver to be created since there is no route to destination. # Connects to listener #2 on QDR.C addr = self.routers[2].addresses[0] # Now delete linkRoutes on QDR.C to eradicate linkRoutes completely local_node = Node.connect(addr, timeout=TIMEOUT) result_list = local_node.query(type='org.apache.qpid.dispatch.router.config.linkRoute').results identity_1 = result_list[0][1] identity_2 = result_list[1][1] identity_3 = result_list[2][1] identity_4 = result_list[3][1] identity_4 = result_list[3][1] cmd = 'DELETE --type=linkRoute --identity=' + identity_1 self.run_qdmanage(cmd=cmd, address=addr) cmd = 'DELETE --type=linkRoute --identity=' + identity_2 self.run_qdmanage(cmd=cmd, address=addr) cmd = 'DELETE --type=linkRoute --identity=' + identity_3 self.run_qdmanage(cmd=cmd, address=addr) cmd = 'DELETE --type=linkRoute --identity=' + identity_4 self.run_qdmanage(cmd=cmd, address=addr) cmd = 'QUERY --type=linkRoute' out = self.run_qdmanage(cmd=cmd, address=addr) self.assertEquals(out.rstrip(), '[]') blocking_connection = BlockingConnection(addr, timeout=3) # Receive on org.apache.dev (this address used to be linkRouted but not anymore since we deleted linkRoutes # on both QDR.C and QDR.B) blocking_receiver = blocking_connection.create_receiver(address="org.apache.dev") apply_options = AtMostOnce() hello_world_1 = "Hello World_1!" # Sender to org.apache.dev blocking_sender = blocking_connection.create_sender(address="org.apache.dev", options=apply_options) msg = Message(body=hello_world_1) # Send a message blocking_sender.send(msg) received_message = blocking_receiver.receive(timeout=5) self.assertEqual(hello_world_1, received_message.body)
def test_yy_query_many_links(self): # This test will fail without the fix for DISPATCH-974 c = BlockingConnection(self.address()) self.logger = Logger(title="test_yy_query_many_links") count = 0 COUNT = 5000 ADDRESS_SENDER = "examples-sender" ADDRESS_RECEIVER = "examples-receiver" # This loop creates 5000 consumer and 5000 producer links with # different addresses while count < COUNT: r = c.create_receiver(ADDRESS_RECEIVER + str(count)) s = c.create_sender(ADDRESS_SENDER + str(count)) count += 1 # Try fetching all 10,000 addresses # This qdmanage query command would fail without the fix # for DISPATCH-974 query_command = 'QUERY --type=org.apache.qpid.dispatch.router.address' outs = json.loads(self.run_qdmanage(query_command)) sender_addresses = 0 receiver_addresses = 0 for out in outs: if ADDRESS_SENDER in out['name']: sender_addresses += 1 if ADDRESS_RECEIVER in out['name']: receiver_addresses += 1 self.assertEqual(sender_addresses, COUNT) self.assertEqual(receiver_addresses, COUNT) query_command = 'QUERY --type=link' outs = json.loads(self.run_qdmanage(query_command)) out_links = 0 in_links = 0 success = False i = 0 while i < 3: i += 1 for out in outs: if out.get('owningAddr'): if ADDRESS_SENDER in out['owningAddr']: in_links += 1 if ADDRESS_RECEIVER in out['owningAddr']: out_links += 1 # If the link count is less than COUNT, try again in 2 seconds # Try after 2 more seconds for a total of 6 seconds. # If the link count is still less than expected count, there # is something wrong, the test has failed. if out_links < COUNT or in_links < COUNT: self.logger.log("out_links=%s, in_links=%s" % (str(out_links), str(in_links))) sleep(2) outs = json.loads(self.run_qdmanage(query_command)) else: self.logger.log("Test success!") success = True break if not success: self.logger.dump() self.assertEqual(out_links, COUNT) self.assertEqual(in_links, COUNT)
class JMSClient(object): """Class JMSClient """ _mh = None _client = None _host = None _port = None _user = None _passw = None _verbose = None _is_connected = None def __init__(self, verbose=False): """Class constructor Called when the object is initialized Args: verbose (bool): verbose mode """ try: self._mh = MasterHead.get_head() self._verbose = verbose if (self._verbose): basicConfig() getLogger().setLevel(DEBUG) except ProtonException as ex: self._mh.demsg('htk_on_error', ex, self._mh.fromhere()) @property def client(self): """ AMQP client property getter """ return self._client @property def host(self): """ server host property getter """ return self._host @property def port(self): """ server port property getter """ return self._port @property def user(self): """ username property getter """ return self._user @property def passw(self): """ user password property getter """ return self._passw @property def verbose(self): """ verbose mode property getter """ return self._verbose @property def is_connected(self): """ is_connected property getter """ return self._is_connected def connect(self, host, port=5672, user=None, passw=None, timeout=10): """Method connects to server Args: host (str): hostname port (str): port user (str): username passw (str): password timeout (int): timeout Returns: bool: result Raises: event: jms_before_connect event: jms_after_connected """ try: msg = 'host:{0}, port:{1}, user:{2}, passw:{3}, timeout:{4}'.format( host, port, user, passw, timeout) self._mh.demsg('htk_on_debug_info', self._mh._trn.msg( 'htk_jms_connecting', msg), self._mh.fromhere()) ev = event.Event( 'jms_before_connect', host, port, user, passw, timeout) if (self._mh.fire_event(ev) > 0): host = ev.argv(0) port = ev.argv(1) user = ev.argv(2) passw = ev.argv(3) timeout = ev.argv(4) self._host = host self._port = port self._user = user self._passw = passw if (ev.will_run_default()): if (self._user == None): self._client = BlockingConnection( 'amqp://{0}:{1}'.format(self._host, self._port), timeout=timeout) else: self._client = BlockingConnection('amqp://{0}:{1}@{2}:{3}'.format(self._user, self._passw, self._host, self._port), timeout=timeout) self._is_connected = True self._mh.demsg('htk_on_debug_info', self._mh._trn.msg( 'htk_jms_connected'), self._mh.fromhere()) ev = event.Event('jms_after_connect') self._mh.fire_event(ev) return True except ProtonException as ex: self._mh.demsg('htk_on_error', ex, self._mh.fromhere()) return False def disconnect(self): """Method disconnects from server Args: none Returns: bool: result """ try: self._mh.demsg('htk_on_debug_info', self._mh._trn.msg( 'htk_jms_disconnecting'), self._mh.fromhere()) if (not self._is_connected): self._mh.demsg('htk_on_warning', self._mh._trn.msg( 'htk_jms_not_connected'), self._mh.fromhere()) return False else: self._client.close() self._is_connected = False self._mh.demsg('htk_on_debug_info', self._mh._trn.msg( 'htk_jms_disconnected'), self._mh.fromhere()) return True except ProtonException as ex: self._mh.demsg('htk_on_error', ex, self._mh.fromhere()) return False def send(self, destination_name, message, destination_type='queue', headers={}): """Method sends message JMS headers - JMSDeliveryMode, JMSPriority, JMSExpiration, JMSType, JMSMessageID, JMSDestination, JMSReplyTo, JMSCorrelationID, JMSTimestamp Args: destination_name (str): queue|topic name message (str): message destination_type (str): queue|topic headers (dict): JMS headers, key - title, value - string Returns: bool: result Raises: event: jms_before_send event: jms_after_send """ try: msg = 'destination_name:{0}, message:{1}, destination_type:{2}, headers:{3}'.format( destination_name, message, destination_type, headers) self._mh.demsg('htk_on_debug_info', self._mh._trn.msg( 'htk_jms_sending_msg', msg), self._mh.fromhere()) if (not self._is_connected): self._mh.demsg('htk_on_warning', self._mh._trn.msg( 'htk_jms_not_connected'), self._mh.fromhere()) return False ev = event.Event( 'jms_before_send', destination_name, message, destination_type, headers) if (self._mh.fire_event(ev) > 0): destination_name = ev.argv(0) message = ev.argv(1) destination_type = ev.argv(2) headers = ev.argv(3) if (ev.will_run_default()): sender = self._client.create_sender( '{0}://{1}'.format(destination_type, destination_name)) headers_new = {} for key, value in headers.items(): if (key in mapping): headers_new[mapping[key]] = value sender.send(Message(body=message, properties=headers_new)) sender.close() self._mh.demsg('htk_on_debug_info', self._mh._trn.msg( 'htk_jms_msg_sent'), self._mh.fromhere()) ev = event.Event('jms_after_send') self._mh.fire_event(ev) return True except ProtonException as ex: self._mh.demsg('htk_on_error', ex, self._mh.fromhere()) return False def receive(self, destination_name, cnt=1): """Method receives messages Args: destination_name (str): queue name cnt (int): count of messages Returns: list: messages as dictionary {'message', JMS headers} Raises: event: jms_before_receive event: jms_after_receive """ try: msg = 'destination_name:{0}, count:{1}'.format( destination_name, cnt) self._mh.demsg('htk_on_debug_info', self._mh._trn.msg( 'htk_jms_receiving_msg', msg), self._mh.fromhere()) if (not self._is_connected): self._mh.demsg('htk_on_warning', self._mh._trn.msg( 'htk_jms_not_connected'), self._mh.fromhere()) return None ev = event.Event('jms_before_receive', destination_name, cnt) if (self._mh.fire_event(ev) > 0): destination_name = ev.argv(0) cnt = ev.argv(1) if (ev.will_run_default()): receiver = self._client.create_receiver( 'queue://{0}'.format(destination_name)) msgs = [] i = 0 while (i < cnt): try: msg = receiver.receive(timeout=1) receiver.accept() msgs.append(msg) i = i + 1 except Timeout: break messages = [] for msg in msgs: message = {} message['message'] = msg.body for key, value in msg.properties.items(): if (key in mapping.values()): message[ list(mapping.keys())[list(mapping.values()).index(key)]] = value messages.append(message) receiver.close() self._mh.demsg('htk_on_debug_info', self._mh._trn.msg( 'htk_jms_msg_received', len(messages)), self._mh.fromhere()) ev = event.Event('jms_after_receive') self._mh.fire_event(ev) return messages except ProtonException as ex: self._mh.demsg('htk_on_error', ex, self._mh.fromhere()) return None def browse(self, destination_name, cnt=100, jms_correlation_id=None, jms_type=None): """Method browses queue Args: destination_name (str): queue name cnt (int): count of messages jms_correlation_id (str): requested JMSCorrelationID jms_type (str): requested JMSType Returns: list: messages as dictionary {'message', JMS headers} Raises: event: jms_before_browse event: jms_after_browse """ try: msg = 'destination_name:{0}, count:{1}, jms_correlation_id:{2}, jms_type:{3}'.format( destination_name, cnt, jms_correlation_id, jms_type) self._mh.demsg('htk_on_debug_info', self._mh._trn.msg( 'htk_jms_browsing', msg), self._mh.fromhere()) if (not self._is_connected): self._mh.demsg('htk_on_warning', self._mh._trn.msg( 'htk_jms_not_connected'), self._mh.fromhere()) return None ev = event.Event('jms_before_browse', destination_name, cnt) if (self._mh.fire_event(ev) > 0): destination_name = ev.argv(0) cnt = ev.argv(1) jms_correlation_id = ev.argv(2) jms_type = ev.argv(3) if (ev.will_run_default()): receiver = self._client.create_receiver( 'queue://{0}'.format(destination_name), options=Copy()) msgs = [] i = 0 while (i < cnt): try: msg = receiver.receive(timeout=1) receiver.accept() correlation_id = None type = None for key, value in msg.properties.items(): if (key == 'properties.correlation-id'): correlation_id = value elif (key == 'message-annotations.x-opt-jms-type'): type = value if ((jms_correlation_id == None or jms_correlation_id == correlation_id) and (jms_type == None or jms_type == type)): msgs.append(msg) i = i + 1 except Timeout: break receiver.close() messages = [] for msg in msgs: message = {} message['message'] = msg.body for key, value in msg.properties.items(): if (key in mapping.values()): message[ list(mapping.keys())[list(mapping.values()).index(key)]] = value messages.append(message) self._mh.demsg('htk_on_debug_info', self._mh._trn.msg( 'htk_jms_msg_received', len(messages)), self._mh.fromhere()) ev = event.Event('jms_after_browse') self._mh.fire_event(ev) return messages except ProtonException as ex: self._mh.demsg('htk_on_error', ex, self._mh.fromhere()) return None
def test_single_connection_protocol_trace(self): qd_manager = QdManager(self, self.address) # Turn off trace logging on all connections. qd_manager.update("org.apache.qpid.dispatch.log", {"enable": "info+"}, name="log/DEFAULT") TEST_ADDR_1 = "EnableConnectionLevelProtocolTraceTest1" MSG_BODY = "EnableConnectionLevelProtocolTraceTestMessage1" CONTAINER_ID_1 = "CONTAINERID_1" container_1 = Container() container_1.container_id = CONTAINER_ID_1 conn_1 = BlockingConnection(self.address, container=container_1) TEST_ADDR_2 = "EnableConnectionLevelProtocolTraceTest1" CONTAINER_ID_2 = "CONTAINERID_2" container_2 = Container() container_2.container_id = CONTAINER_ID_2 conn_2 = BlockingConnection(self.address, container=container_2) results = qd_manager.query("org.apache.qpid.dispatch.connection") conn_id = None for result in results: if result['container'] == CONTAINER_ID_1: conn_id = result['identity'] # Turn on trace logging for connection with identity conn_id qd_manager.update("org.apache.qpid.dispatch.connection", {"enableProtocolTrace": "true"}, identity=conn_id) blocking_receiver_1 = conn_1.create_receiver(address=TEST_ADDR_1) blocking_sender_1 = conn_1.create_sender(address=TEST_ADDR_1, options=apply_options) blocking_receiver_2 = conn_2.create_receiver(address=TEST_ADDR_2) blocking_sender_2 = conn_2.create_sender(address=TEST_ADDR_2, options=apply_options) num_attaches_1 = 0 num_attaches_2 = 0 logs = qd_manager.get_log() for log in logs: if 'PROTOCOL' in log[0]: if "@attach" in log[2] and TEST_ADDR_1 in log[2]: num_attaches_1 += 1 elif "@attach" in log[2] and TEST_ADDR_2 in log[2]: num_attaches_2 += 1 # num_attaches_1 for address TEST_ADDR_1 must be 4, two attaches to/from sender and receiver self.assertTrue(num_attaches_1 == 4) # num_attaches_2 for address TEST_ADDR_2 must be 0 since trace was not # turned on for that connection self.assertTrue(num_attaches_2 == 0) # Now turn off the connection tracing on that connection qd_manager.update("org.apache.qpid.dispatch.connection", {"enableProtocolTrace": "off"}, identity=conn_id) blocking_receiver_1.close() blocking_sender_1.close() # Since tracing was turned off, there should be no detaches logs = qd_manager.get_log() num_detaches = 0 for log in logs: if 'PROTOCOL' in log[0]: if "@detach" in log[2]: num_detaches += 1 self.assertTrue(num_detaches == 0) blocking_receiver_2.close() blocking_sender_2.close() conn_1.close() conn_2.close()
# Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # from proton import Message from proton.utils import BlockingConnection from proton.handlers import IncomingMessageHandler conn = BlockingConnection("localhost:5672") receiver = conn.create_receiver("examples") sender = conn.create_sender("examples") sender.send(Message(body=u"Hello World!")) msg = receiver.receive(timeout=30) print msg.body receiver.accept() conn.close()
def test_forwarding(self): """ Simple forwarding over a single 0-10 exchange """ config = [ ('exchange', { 'address': 'Address1', 'name': 'Exchange1', 'matchMethod': 'amqp' }), # two different patterns, same next hop: ('binding', { 'name': 'binding1', 'exchangeName': 'Exchange1', 'bindingKey': 'a.*', 'nextHopAddress': 'nextHop1' }), ('binding', { 'name': 'binding2', 'exchangeName': 'Exchange1', 'bindingKey': 'a.b', 'nextHopAddress': 'nextHop1' }), # duplicate patterns, different next hops: ('binding', { 'name': 'binding3', 'exchangeName': 'Exchange1', 'bindingKey': 'a.c.#', 'nextHopAddress': 'nextHop1' }), ('binding', { 'name': 'binding4', 'exchangeName': 'Exchange1', 'bindingKey': 'a.c.#', 'nextHopAddress': 'nextHop2' }), # match for nextHop2 only ('binding', { 'name': 'binding5', 'exchangeName': 'Exchange1', 'bindingKey': 'a.b.c', 'nextHopAddress': 'nextHop2' }) ] router = self._create_router('A', config) # create clients for message transfer conn = BlockingConnection(router.addresses[0]) sender = conn.create_sender(address="Address1", options=AtMostOnce()) nhop1 = conn.create_receiver(address="nextHop1", credit=100) nhop2 = conn.create_receiver(address="nextHop2", credit=100) # verify initial metrics self._validate_exchange(router, name='Exchange1', bindingCount=5, receivedCount=0, droppedCount=0, forwardedCount=0, divertedCount=0) for b in range(5): self._validate_binding(router, name='binding%s' % (b + 1), matchedCount=0) # send message with subject "a.b" # matches (binding1, binding2) # forwarded to NextHop1 only sender.send(Message(subject='a.b', body='A')) self.assertEqual('A', nhop1.receive(timeout=TIMEOUT).body) # send message with subject "a.c" # matches (bindings 1,3,4) # -> NextHop1, NextHop2 sender.send(Message(subject='a.c', body='B')) self.assertEqual('B', nhop1.receive(timeout=TIMEOUT).body) self.assertEqual('B', nhop2.receive(timeout=TIMEOUT).body) # send message with subject "a.c.d" # matches bindings 3,4 # -> NextHop1, NextHop2 sender.send(Message(subject='a.c.d', body='C')) self.assertEqual('C', nhop1.receive(timeout=TIMEOUT).body) self.assertEqual('C', nhop2.receive(timeout=TIMEOUT).body) # send message with subject "x.y.z" # no binding match - expected to drop # not forwarded sender.send(Message(subject='x.y.z', body=["I am Noone"])) # send message with subject "a.b.c" # matches binding5 # -> NextHop2 sender.send(Message(subject='a.b.c', body='D')) self.assertEqual('D', nhop2.receive(timeout=TIMEOUT).body) # ensure there are no more messages on either hop: self.assertRaises(Timeout, nhop1.receive, timeout=0.25) self.assertRaises(Timeout, nhop2.receive, timeout=0.25) # validate counters self._validate_binding(router, name='binding1', matchedCount=2) self._validate_binding(router, name='binding2', matchedCount=1) self._validate_binding(router, name='binding3', matchedCount=2) self._validate_binding(router, name='binding4', matchedCount=2) self._validate_binding(router, name='binding5', matchedCount=1) self._validate_exchange(router, name="Exchange1", receivedCount=5, forwardedCount=4, divertedCount=0, droppedCount=1) conn.close()
def test_zzz_qdmanage_delete_link_route(self): """ We are deleting the link route using qdmanage short name. This should be the last test to run """ # First delete linkRoutes on QDR.B local_node = Node.connect(self.routers[1].addresses[0], timeout=TIMEOUT) result_list = local_node.query(type='org.apache.qpid.dispatch.router.config.linkRoute').results identity_1 = result_list[0][1] identity_2 = result_list[1][1] identity_3 = result_list[2][1] identity_4 = result_list[3][1] cmd = 'DELETE --type=linkRoute --identity=' + identity_1 self.run_qdmanage(cmd=cmd, address=self.routers[1].addresses[0]) cmd = 'DELETE --type=linkRoute --identity=' + identity_2 self.run_qdmanage(cmd=cmd, address=self.routers[1].addresses[0]) cmd = 'DELETE --type=linkRoute --identity=' + identity_3 self.run_qdmanage(cmd=cmd, address=self.routers[1].addresses[0]) cmd = 'DELETE --type=linkRoute --identity=' + identity_4 self.run_qdmanage(cmd=cmd, address=self.routers[1].addresses[0]) cmd = 'QUERY --type=linkRoute' out = self.run_qdmanage(cmd=cmd, address=self.routers[1].addresses[0]) self.assertEquals(out.rstrip(), '[]') # linkRoutes now gone on QDR.B but remember that it still exist on QDR.C # We will now try to create a receiver on address org.apache.dev on QDR.C. # Since the linkRoute on QDR.B is gone, QDR.C # will not allow a receiver to be created since there is no route to destination. # Connects to listener #2 on QDR.C addr = self.routers[2].addresses[1] # Now delete linkRoutes on QDR.C to eradicate linkRoutes completely local_node = Node.connect(addr, timeout=TIMEOUT) result_list = local_node.query(type='org.apache.qpid.dispatch.router.config.linkRoute').results identity_1 = result_list[0][1] identity_2 = result_list[1][1] identity_3 = result_list[2][1] identity_4 = result_list[3][1] cmd = 'DELETE --type=linkRoute --identity=' + identity_1 self.run_qdmanage(cmd=cmd, address=addr) cmd = 'DELETE --type=linkRoute --identity=' + identity_2 self.run_qdmanage(cmd=cmd, address=addr) cmd = 'DELETE --type=linkRoute --identity=' + identity_3 self.run_qdmanage(cmd=cmd, address=addr) cmd = 'DELETE --type=linkRoute --identity=' + identity_4 self.run_qdmanage(cmd=cmd, address=addr) cmd = 'QUERY --type=linkRoute' out = self.run_qdmanage(cmd=cmd, address=addr) self.assertEquals(out.rstrip(), '[]') blocking_connection = BlockingConnection(addr, timeout=3) # Receive on org.apache.dev (this address used to be linkRouted but not anymore since we deleted linkRoutes # on both QDR.C and QDR.B) blocking_receiver = blocking_connection.create_receiver(address="org.apache.dev") apply_options = AtMostOnce() hello_world_1 = "Hello World_1!" # Sender to org.apache.dev blocking_sender = blocking_connection.create_sender(address="org.apache.dev", options=apply_options) msg = Message(body=hello_world_1) # Send a message blocking_sender.send(msg) received_message = blocking_receiver.receive(timeout=5) self.assertEqual(hello_world_1, received_message.body)
def test_yy_query_many_links(self): # This test will fail without the fix for DISPATCH-974 c = BlockingConnection(self.router.addresses[0]) count = 0 links = [] COUNT = 5000 ADDRESS_SENDER = "examples-sender" ADDRESS_RECEIVER = "examples-receiver" # This loop creates 5000 consumer and 5000 producer links while True: count += 1 r = c.create_receiver(ADDRESS_RECEIVER + str(count)) links.append(r) s = c.create_sender(ADDRESS_SENDER + str(count)) links.append(c) if count == COUNT: break # Now we run qdstat command and check if we got back details # about all the 10000 links # We do not specify the limit which means unlimited # which means get everything that is there. outs = self.run_qdstat(['--links']) out_list = outs.split("\n") out_links = 0 in_links = 0 for out in out_list: if "endpoint in" in out and ADDRESS_SENDER in out: in_links += 1 if "endpoint out" in out and ADDRESS_RECEIVER in out: out_links += 1 self.assertEqual(in_links, COUNT) self.assertEqual(out_links, COUNT) # Run qdstat with a limit more than 10,000 outs = self.run_qdstat(['--links', '--limit=15000']) out_list = outs.split("\n") out_links = 0 in_links = 0 for out in out_list: if "endpoint in" in out and ADDRESS_SENDER in out: in_links += 1 if "endpoint out" in out and ADDRESS_RECEIVER in out: out_links += 1 self.assertEqual(in_links, COUNT) self.assertEqual(out_links, COUNT) # Run qdstat with a limit less than 10,000 outs = self.run_qdstat(['--links', '--limit=2000']) out_list = outs.split("\n") links = 0 for out in out_list: if "endpoint" in out and "examples" in out: links += 1 self.assertEqual(links, 2000) # Run qdstat with a limit less than 10,000 # repeat with --csv outs = self.run_qdstat(['--links', '--limit=2000', '--csv']) out_list = outs.split("\n") links = 0 for out in out_list: if "endpoint" in out and "examples" in out: links += 1 self.assertEqual(links, 2000) # Run qdstat with a limit of 700 because 700 # is the maximum number of rows we get per request outs = self.run_qdstat(['--links', '--limit=700']) out_list = outs.split("\n") links = 0 for out in out_list: if "endpoint" in out and "examples" in out: links += 1 self.assertEqual(links, 700) # Run qdstat with a limit of 700 because 700 # is the maximum number of rows we get per request # repeat with --csv outs = self.run_qdstat(['--links', '--limit=700', '--csv']) out_list = outs.split("\n") links = 0 for out in out_list: if "endpoint" in out and "examples" in out: links += 1 self.assertEqual(links, 700) # Run qdstat with a limit of 500 because 700 # is the maximum number of rows we get per request # and we want to try something less than 700 outs = self.run_qdstat(['--links', '--limit=500']) out_list = outs.split("\n") links = 0 for out in out_list: if "endpoint" in out and "examples" in out: links += 1 self.assertEqual(links, 500) # Run qdstat with a limit of 500 because 700 # is the maximum number of rows we get per request # and we want to try something less than 700 # repeat with --csv outs = self.run_qdstat(['--links', '--limit=500', '--csv']) out_list = outs.split("\n") links = 0 for out in out_list: if "endpoint" in out and "examples" in out: links += 1 self.assertEqual(links, 500) # DISPATCH-1485. Try to run qdstat with a limit=0. Without the fix for DISPATCH-1485 # this following command will hang and the test will fail. outs = self.run_qdstat(['--links', '--limit=0']) out_list = outs.split("\n") links = 0 for out in out_list: if "endpoint" in out and "examples" in out: links += 1 self.assertEqual(links, COUNT * 2) # DISPATCH-1485. Try to run qdstat with a limit=0. Without the fix for DISPATCH-1485 # this following command will hang and the test will fail. # repeat with --csv outs = self.run_qdstat(['--links', '--limit=0', '--csv']) out_list = outs.split("\n") links = 0 for out in out_list: if "endpoint" in out and "examples" in out: links += 1 self.assertEqual(links, COUNT * 2) # This test would fail without the fix for DISPATCH-974 outs = self.run_qdstat(['--address']) out_list = outs.split("\n") sender_addresses = 0 receiver_addresses = 0 for out in out_list: if ADDRESS_SENDER in out: sender_addresses += 1 if ADDRESS_RECEIVER in out: receiver_addresses += 1 self.assertEqual(sender_addresses, COUNT) self.assertEqual(receiver_addresses, COUNT) # Test if there is a non-zero uptime for the router in the output of # qdstat -g non_zero_seconds = False outs = self.run_qdstat(args=None) parts = outs.split("\n") for part in parts: if "Uptime" in part: uptime_parts = part.split(" ") for uptime_part in uptime_parts: if uptime_part.startswith("000"): time_parts = uptime_part.split(":") if int(time_parts[3]) > 0: non_zero_seconds = True if not non_zero_seconds: if int(time_parts[2]) > 0: non_zero_seconds = True self.assertTrue(non_zero_seconds) c.close()