Exemple #1
0
 def test_connection_properties(self):
     ensureCanTestExtendedSASL()
     server = ConnPropertiesServer(Url(host="127.0.0.1",
                                       port=free_tcp_port()),
                                   timeout=self.timeout)
     server.start()
     server.wait()
     connection = BlockingConnection(
         server.url,
         timeout=self.timeout,
         properties=CONNECTION_PROPERTIES,
         offered_capabilities=OFFERED_CAPABILITIES,
         desired_capabilities=DESIRED_CAPABILITIES)
     client = SyncRequestResponse(connection)
     client.connection.close()
     server.join(timeout=self.timeout)
     self.assertEquals(server.properties_received, True)
     self.assertEquals(server.offered_capabilities_received, True)
     self.assertEquals(server.desired_capabilities_received, True)
Exemple #2
0
    def test_request_response(self):
        ensureCanTestExtendedSASL()
        def test(name, address="x"):
            for i in range(5):
                body="%s%s" % (name, i)
                response = client.call(Message(address=address, body=body))
                self.assertEquals(response.address, client.reply_to)
                self.assertEquals(response.body, body)

        server = EchoServer(Url(host="127.0.0.1", port=free_tcp_port()), self.timeout)
        server.start()
        server.wait()
        connection = BlockingConnection(server.url, timeout=self.timeout)
        client = SyncRequestResponse(connection)
        try:
            test("foo")         # Simple request/resposne
        finally:
            client.connection.close()
        server.join(timeout=self.timeout)
Exemple #3
0
    def test_max_frame_max_session_zero(self):
        # Set up a connection to get the Open and a receiver to get a Begin frame in the log
        bc = BlockingConnection(self.router.addresses[0])
        bc.create_receiver("xxx")
        bc.close()

        with open('../setUpClass/MaxFrameMaxSessionFramesZero.log',
                  'r') as router_log:
            log_lines = router_log.read().split("\n")
            open_lines = [s for s in log_lines if "-> @open" in s]
            # max-frame gets set to protocol min
            self.assertIn(' max-frame-size=512,', open_lines[0])
            begin_lines = [s for s in log_lines if "-> @begin" in s]
            # incoming-window should be 2^31-1 (64-bit) or
            # (2^31-1) / max-frame-size (32-bit)
            is_64bits = sys.maxsize > 2**32
            expected = " incoming-window=2147483647," if is_64bits else \
                (" incoming-window=%d," % int(2147483647 / 512))
            self.assertIn(expected, begin_lines[0])
Exemple #4
0
    def connect(cls,
                url=None,
                router=None,
                timeout=10,
                ssl_domain=None,
                sasl=None,
                edge_router=None):
        """
        Return a Node connected with the given parameters, see L{connection}
        @param url: URL of the management node.
        @param router: If address does not contain a path, use the management node for this router ID.
        If not specified and address does not contain a path, use the default management node.
        :param edge_router:
        :param timeout:
        :param sasl:
        :param ssl_domain:
        """
        url_ = Url(url)  # Convert string to Url class.

        if url_.path is not None:
            path = url_.path
        elif router:
            path = '_topo/0/%s/$management' % router
        elif edge_router:
            path = '_edge/%s/$management' % edge_router
        else:
            path = u'$management'
        connection = BlockingConnection(
            url,
            timeout=timeout,
            ssl_domain=ssl_domain,
            sasl_enabled=bool(ssl_domain or sasl),
            allowed_mechs=str(sasl.mechs)
            if sasl and sasl.mechs is not None else None,
            user=str(sasl.user) if sasl and sasl.user is not None else None,
            password=str(sasl.password)
            if sasl and sasl.password is not None else None)
        try:
            return cls(connection, path)
        except Exception:
            # ownership of connection has not been given to a new Node; close the connection
            connection.close()
            raise
Exemple #5
0
    def test_router_core_logger(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_BODY = "LOGTEST"
        msg = Message(body=TEST_MSG_BODY)
        blocking_sender.send(msg)
        received_message = blocking_receiver.receive()
        self.assertEqual(TEST_MSG_BODY, received_message.body)
        qd_manager = QdManager(self, self.address)
        logs = qd_manager.get_log()

        router_core_found = False
        for log in logs:
            if u'ROUTER_CORE' in log[0]:
                router_core_found = True
                break

        self.assertTrue(router_core_found)

        core_log_file_found = True
        all_lines_router_core = True
        try:
            # Before the fix to DISPATCH-1575, this file will not be
            # created because the router core module was logging to the ROUTER
            # module instead of the ROUTER_CORE module.
            with open('../setUpClass/test-router-core.log', 'r') as core_log:
                for line in core_log:
                    # Every line in the file must log to the router core module.
                    if not "ROUTER_CORE" in line:
                        all_lines_router_core = False
                        break
        except:
            core_log_file_found = False

        self.assertTrue(core_log_file_found)
        self.assertTrue(all_lines_router_core)
Exemple #6
0
    def test_partial_link_route_match_1(self):
        """
        This test is pretty much the same as the previous test (test_partial_link_route_match) but the connection is
        made to router QDR.B instead of QDR.C and we expect to see the same behavior.
        """
        hello_world_2 = "Hello World_2!"
        addr = self.routers[1].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  to org.apache.dev
        blocking_sender = blocking_connection.create_sender(
            address="org.apache.dev", options=apply_options)
        msg = Message(body=hello_world_2)
        # Send a message
        blocking_sender.send(msg)

        received_message = blocking_receiver.receive()

        self.assertEqual(hello_world_2, 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.dev').deliveriesEgress)

        self.assertEqual(
            1,
            local_node.read(type='org.apache.qpid.dispatch.router.address',
                            name='M0org.apache.dev').deliveriesIngress)

        blocking_connection.close()
Exemple #7
0
    def connection(url=None, timeout=10, ssl_domain=None, sasl=None):
        """
        Return a BlockingConnection for connection to a managemenet node
        """
        url = Url(url)

        url.path = u'$management'

        if ssl_domain:
            sasl_enabled = True
        else:
            sasl_enabled = True if sasl else False

        return BlockingConnection(url,
                                  timeout=timeout,
                                  ssl_domain=ssl_domain,
                                  sasl_enabled=sasl_enabled,
                                  allowed_mechs=str(sasl.mechs) if sasl and sasl.mechs != None else None,
                                  user=str(sasl.user) if sasl else None,
                                  password=str(sasl.password) if sasl else None)
Exemple #8
0
    def test_max_session_frames_default(self):
        # Set up a connection to get the Open and a receiver to get a Begin frame in the log
        bc = BlockingConnection(self.router.addresses[0])
        bc.create_receiver("xxx")
        bc.close()

        with open('../setUpClass/MaxSessionFramesDefault.log',
                  'r') as router_log:
            log_lines = router_log.read().split("\n")
            open_lines = [s for s in log_lines if "-> @open" in s]
            # if frame size not set then a default is used
            self.assertIn(" max-frame-size=16384", open_lines[0])
            begin_lines = [s for s in log_lines if "-> @begin" in s]
            # incoming-window should be 2^31-1 (64-bit) or
            # (2^31-1) / max-frame-size (32-bit)
            is_64bits = sys.maxsize > 2**32
            expected = " incoming-window=2147483647," if is_64bits else \
                (" incoming-window=%d," % int(2147483647 / 16384))
            #self.assertIn(expected, begin_lines[0], "Expected:'%s' not found in '%s'" % (expected, begin_lines[0]))
            self.assertIn(expected, begin_lines[0])
    def test_max_frame_max_session_too_big(self):
        # Set up a connection to get the Open and a receiver to get a Begin frame in the log
        bc = BlockingConnection(self.router.addresses[0])
        bc.create_receiver("xxx")
        bc.close()

        with open('../setUpClass/MaxFrameMaxSessionFramesTooBig.log',
                  'r') as router_log:
            log_lines = router_log.read().split("\n")
            open_lines = [s for s in log_lines if "-> @open" in s]
            # max-frame is from the config
            self.assertTrue(' max-frame-size=1000000,' in open_lines[0])
            begin_lines = [s for s in log_lines if "-> @begin" in s]
            # incoming-window is truncated
            self.assertTrue(" incoming-window=2147," in begin_lines[0])
            warning_lines = [s for s in log_lines if "(warning)" in s]
            self.assertTrue(len(warning_lines) == 1)
            self.assertTrue(
                "requested maxSessionFrames truncated from 5000000 to 2147" in
                warning_lines[0])
    def test_sync_request_response_blocking_connection_no_fd_leaks(self):
        with test_broker() as tb:
            sockname = tb.get_acceptor_sockname()
            url = "{0}:{1}".format(*sockname)
            opts = namedtuple('Opts', ['address', 'timeout'])(address=url,
                                                              timeout=3)

            with no_fd_leaks(self):
                client = SyncRequestResponse(
                    BlockingConnection(url,
                                       opts.timeout,
                                       allowed_mechs="ANONYMOUS"), "somequeue")
                try:
                    request = "One Two Three Four"
                    response = client.call(Message(body=request))
                    self.assertEqual(response.body, "ONE TWO THREE FOUR")
                finally:
                    client.connection.close()

        gc.collect()
Exemple #11
0
    def test_link_route_lookup_ok(self):
        """
        verify a link route address can be looked up successfully for both
        locally attached and remotely attached containers
        """

        # fire up a fake broker attached to the router local to the edge router
        # wait until both in and out addresses are ready
        fb = FakeBroker(self.INT_A.broker_connector,
                        container_id='FakeBrokerA')
        self.INT_A.wait_address("org.apache.A", containers=1, count=2)

        # create a fake edge and lookup the target address
        bc = BlockingConnection(self.INT_A.edge_listener, timeout=TIMEOUT)
        srr = SyncRequestResponse(bc, self.QD_TERMINUS_ADDRESS_LOOKUP)

        for direction in [True, False]:
            # True = direction inbound (receiver) False = direction outbound (sender)
            rsp = self._check_response(
                srr.call(self._lookup_request("org.apache.A.foo", direction)))
            self.assertEqual(self.QCM_ADDR_LOOKUP_OK, rsp[0])
            self.assertTrue(rsp[1])
            self.assertTrue(rsp[2])

        # shutdown fake router
        fb.join()

        # now fire up a fake broker attached to the remote router
        fb = FakeBroker(self.INT_B.broker_connector,
                        container_id='FakeBrokerB')
        self.INT_A.wait_address("org.apache.B", remotes=1, count=2)

        for direction in [True, False]:
            rsp = self._check_response(
                srr.call(self._lookup_request("org.apache.B.foo", direction)))
            self.assertEqual(self.QCM_ADDR_LOOKUP_OK, rsp[0])
            self.assertTrue(rsp[1])
            self.assertTrue(rsp[2])

        fb.join()
        bc.close()
Exemple #12
0
    def __init__(self, router_address, timeout, router_id=None, edge_id=None):
        """
        @param router_address: the network address of the router to manage.
        @param timeout: raise an error if a management operation blocks longer
        than timeout seconds.
        @param router_id: identity of remote router.  Use this if the router to
        be managed is not the router at router_address.  This can be used to
        access a remote router using a local router as a proxy.
        @param edge_id: like router_id except remote is an edge router.

        Note that router_id and edge_id are mutually exclusive
        """
        assert (not (edge_id and router_id))
        self._conn = BlockingConnection(router_address, timeout=timeout)
        if router_id:
            self._mgmt_address = u'_topo/0/%s/$management' % router_id
        elif edge_id:
            self._mgmt_address = u'_edge/%s/$management' % edge_id
        else:
            self._mgmt_address = u'$management'
        self._client = SyncRequestResponse(self._conn, self._mgmt_address)
Exemple #13
0
 def test_allowed_mechs_anonymous(self):
     # All this test does it make sure that if we pass allowed_mechs to BlockingConnection, it is actually used.
     server = ConnPropertiesServer(Url(host="127.0.0.1",
                                       port=free_tcp_port()),
                                   timeout=self.timeout)
     server.start()
     server.wait()
     # An ANONYMOUS allowed_mechs will work, anonymous connections are allowed by ConnPropertiesServer
     connection = BlockingConnection(
         server.url,
         timeout=self.timeout,
         properties=CONNECTION_PROPERTIES,
         offered_capabilities=OFFERED_CAPABILITIES,
         desired_capabilities=DESIRED_CAPABILITIES,
         allowed_mechs=ANONYMOUS)
     client = SyncRequestResponse(connection)
     client.connection.close()
     server.join(timeout=self.timeout)
     self.assertEquals(server.properties_received, True)
     self.assertEquals(server.offered_capabilities_received, True)
     self.assertEquals(server.desired_capabilities_received, True)
Exemple #14
0
 def test_allowed_mechs_external(self):
     # All this test does it make sure that if we pass allowed_mechs to BlockingConnection, it is actually used.
     port = free_tcp_port()
     server = ConnPropertiesServer(Url(host="127.0.0.1", port=port),
                                   timeout=self.timeout)
     server.start()
     server.wait()
     try:
         # This will cause an exception because we are specifying allowed_mechs as EXTERNAL. The SASL handshake will fail because the server is not setup to handle EXTERNAL
         connection = BlockingConnection(
             server.url,
             timeout=self.timeout,
             properties=CONNECTION_PROPERTIES,
             offered_capabilities=OFFERED_CAPABILITIES,
             desired_capabilities=DESIRED_CAPABILITIES,
             allowed_mechs=EXTERNAL)
         self.fail("Expected ConnectionException")
     except ConnectionException as e:
         self.assertTrue('amqp:unauthorized-access' in str(e),
                         "expected unauthorized-access")
     server.join(timeout=self.timeout)
 def collect_metric(self, entityType):
     try:
         client = SyncRequestResponse(
             BlockingConnection("127.0.0.1:5672", 30), "$management")
         try:
             properties = {}
             properties["entityType"] = entityType
             properties["operation"] = "QUERY"
             properties["name"] = "self"
             message = Message(body=None, properties=properties)
             response = client.call(message)
             if response == None:
                 return response
             else:
                 return RouterResponse(response)
         finally:
             client.connection.close()
     except:
         e = sys.exc_info()[0]
         print("Error querying router for metrics: %s" % e)
         return None
    def test_full_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' 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 linkRoute attribute('org.apache.').
        """
        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)
        # 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='M0org.apache').deliveriesEgress)

        self.assertEqual(1, local_node.read(type='org.apache.qpid.dispatch.router.address',
                                            name='M0org.apache').deliveriesIngress)

        blocking_connection.close()
Exemple #17
0
    def collect(self):
        collector_map = self.create_collector_map()
        fetcher_map = self.create_entity_map(collector_map)
        connection = None
        print("Collecting metrics")

        try:
            connection = BlockingConnection("amqps://" + self.router_host +
                                            ":" + str(self.router_port),
                                            30,
                                            None,
                                            self.ssl_domain,
                                            allowed_mechs=self.allowed_mechs,
                                            sasl_enabled=self.sasl_enabled,
                                            container_id="router-metrics")
            client = SyncRequestResponse(connection, "$management")
            for fetcher in fetcher_map:
                response = fetcher(client)
                if response != None:
                    for collector in fetcher_map[fetcher]:
                        for entity in response.get_results():
                            if response.contains(entity, collector.filter):
                                labels = []
                                for l in collector.labels:
                                    label_idx = response.get_index(l)
                                    if label_idx != None and entity[
                                            label_idx] != None:
                                        labels.append(entity[label_idx])
                                    else:
                                        labels.append("")
                                value = entity[response.get_index(
                                    collector.name)]
                                collector.add(labels, int(value))
        finally:
            if connection != None:
                connection.close()

        for collector in collector_map.itervalues():
            yield collector.metric()
Exemple #18
0
    def connection(url=None,
                   router=None,
                   timeout=10,
                   ssl_domain=None,
                   sasl=None,
                   edge_router=None):
        """Return a BlockingConnection suitable for connecting to a management node
        @param url: URL of the management node.
        @param router: If address does not contain a path, use the management node for this router ID.
            If not specified and address does not contain a path, use the default management node.
        """
        url = Url(url)  # Convert string to Url class.

        if url.path is None:
            if router:
                url.path = u'_topo/0/%s/$management' % router
            elif edge_router:
                url.path = u'_edge/%s/$management' % edge_router
            else:
                url.path = u'$management'

        if ssl_domain:
            sasl_enabled = True
        else:
            sasl_enabled = True if sasl else False

        # if sasl_mechanism is unicode, convert it to python string
        return BlockingConnection(
            url,
            timeout=timeout,
            ssl_domain=ssl_domain,
            sasl_enabled=sasl_enabled,
            allowed_mechs=str(sasl.mechs)
            if sasl and sasl.mechs != None else None,
            user=str(sasl.user) if sasl and sasl.user != None else None,
            password=str(sasl.password)
            if sasl and sasl.password != None else None)
    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 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()
Exemple #21
0
    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()
Exemple #22
0
    def connection(url=None,
                   router=None,
                   timeout=10,
                   ssl_domain=None,
                   sasl=None,
                   edge_router=None):
        """Return a BlockingConnection suitable for connecting to a management node
        """
        if ssl_domain:
            sasl_enabled = True
        else:
            sasl_enabled = True if sasl else False

        # if sasl_mechanism is unicode, convert it to python string
        return BlockingConnection(
            url,
            timeout=timeout,
            ssl_domain=ssl_domain,
            sasl_enabled=sasl_enabled,
            allowed_mechs=str(sasl.mechs)
            if sasl and sasl.mechs is not None else None,
            user=str(sasl.user) if sasl and sasl.user is not None else None,
            password=str(sasl.password)
            if sasl and sasl.password is not None else None)
Exemple #23
0
except ImportError:
    from urllib import quote_plus

import perftest


with open(os.path.abspath(os.path.join(os.path.dirname(__file__),
                                       '../config.json')
                          ), 'r') as read_file:
    config = json.load(read_file)

TOPIC_NAME = 'test_topic_4'
SERVICE_NAMESPACE = config['service_namespace']
KEY_NAME = config['key_name']
KEY_VALUE = config['key_value']

CONN_STR = 'amqps://{}:{}@{}.servicebus.windows.net'.format(
    KEY_NAME, quote_plus(KEY_VALUE, safe=''), SERVICE_NAMESPACE)

conn = BlockingConnection(CONN_STR, allowed_mechs='PLAIN')
sender = conn.create_sender(TOPIC_NAME)

producer = perftest.PerfProducer(conn, sender)
producer.start()

for i in range(1, 30):
    time.sleep(1)
    print ("producer sent {}".format(producer.rate.print_rate()))

producer.stop()
    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()
    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_01_toggle_default_trace_logging(self):
        hello_world_1 = "Hello World_1!"
        hello_world_2 = "Hello World_2!"
        hello_world_3 = "Hello World_3!"
        hello_world_4 = "Hello World_4!"
        qd_manager = QdManager(self, self.address)

        blocking_connection = BlockingConnection(self.address)
        TEST_ADDR = "apachetest1"
        self.create_sender_receiver(TEST_ADDR, hello_world_1,
                                    blocking_connection)

        # STEP 1: Make sure that proton trace logging is turned on already.
        # Search for attach frames in the log for address TEST_ADDR. There should be 4 attaches
        num_attaches = 0
        logs = qd_manager.get_log()
        for log in logs:
            if u'SERVER' in log[0]:
                if "@attach" in log[2] and TEST_ADDR in log[2]:
                    num_attaches += 1
        # num_attaches for address TEST_ADDR must be 4, two attaches to/from sender and receiver
        self.assertTrue(num_attaches == 4)

        # STEP 2: Turn off trace logging using qdmanage
        qd_manager.update("org.apache.qpid.dispatch.log", {"enable": "info+"},
                          name="log/DEFAULT")

        # Step 3: Now, router trace logging is turned off (has been set to info+)
        # Create the sender and receiver again on a different address and make
        # sure that the attaches are NOT showing in the log for that address.

        TEST_ADDR = "apachetest2"
        self.create_sender_receiver(TEST_ADDR, hello_world_2,
                                    blocking_connection)

        # STEP 3: Count the nimber of attaches for address TEST_ADDR, there should be none
        num_attaches = 0
        logs = qd_manager.get_log()
        for log in logs:
            if u'SERVER' in log[0]:
                if "@attach" in log[2] and TEST_ADDR in log[2]:
                    num_attaches += 1
        # There should be no attach frames with address TEST_ADDR
        # because we turned of trace logging.
        self.assertTrue(num_attaches == 0)

        # STEP 4: Tuen trace logging back on again and make sure num_attaches = 4
        TEST_ADDR = "apachetest3"
        qd_manager.update("org.apache.qpid.dispatch.log", {"enable": "trace+"},
                          name="log/DEFAULT")
        self.create_sender_receiver(TEST_ADDR, hello_world_3,
                                    blocking_connection)

        # STEP 3: Count the number of attaches for address TEST_ADDR, there should be 4
        num_attaches = 0
        logs = qd_manager.get_log()
        for log in logs:
            if u'SERVER' in log[0]:
                if "@attach" in log[2] and TEST_ADDR in log[2]:
                    num_attaches += 1
        # There should be 4 attach frames with address TEST_ADDR
        # because we turned on trace logging.
        self.assertTrue(num_attaches == 4)

        # Create a brand new blocking connection  and make sure that connection
        # is logging at trace level as well.
        num_attaches = 0
        TEST_ADDR = "apachetest4"
        self.create_sender_receiver(TEST_ADDR, hello_world_4)
        num_attaches = 0
        logs = qd_manager.get_log()
        for log in logs:
            if u'SERVER' in log[0]:
                if "@attach" in log[2] and TEST_ADDR in log[2]:
                    num_attaches += 1

        self.assertTrue(num_attaches == 4)
    def test_02_toggle_server_trace_logging(self):
        """
        This test is similar to test_01_toggle_default_trace_logging but it tests the
        SERVER log level.
        """
        hello_world_5 = "Hello World_5!"
        hello_world_6 = "Hello World_6!"
        hello_world_7 = "Hello World_7!"
        TEST_ADDR = "apachetest5"

        # Step 1. Turn off trace logging for module DEFAULT and enable trace logging
        #         for the SERVER module and make sure it works.
        qd_manager = QdManager(self, self.address)
        # Set log level to info+ on the DEFAULT module
        qd_manager.update("org.apache.qpid.dispatch.log", {"enable": "info+"},
                          name="log/DEFAULT")
        # Set log level to trace+ on the SERVER module
        qd_manager.update("org.apache.qpid.dispatch.log", {"enable": "trace+"},
                          name="log/SERVER")
        blocking_connection = BlockingConnection(self.address)

        self.create_sender_receiver(TEST_ADDR, hello_world_5,
                                    blocking_connection)
        # Count the nimber of attaches for address TEST_ADDR, there should be 4
        num_attaches = 0
        logs = qd_manager.get_log()
        for log in logs:
            if u'SERVER' in log[0]:
                if "@attach" in log[2] and TEST_ADDR in log[2]:
                    num_attaches += 1
        # There should be 4 attach frames with address TEST_ADDR
        # because we turned on trace logging.
        self.assertTrue(num_attaches == 4)

        TEST_ADDR = "apachetest6"
        qd_manager.update("org.apache.qpid.dispatch.log", {"enable": "info+"},
                          name="log/SERVER")

        self.create_sender_receiver(TEST_ADDR, hello_world_6,
                                    blocking_connection)

        # Count the nimber of attaches for address TEST_ADDR, there should be 0
        num_attaches = 0
        logs = qd_manager.get_log()
        for log in logs:
            if u'SERVER' in log[0]:
                if "@attach" in log[2] and TEST_ADDR in log[2]:
                    num_attaches += 1
        self.assertTrue(num_attaches == 0)

        # Create a brand new blocking connection  and make sure that connection
        # is logging at info level as well.
        TEST_ADDR = "apachetest7"
        self.create_sender_receiver(TEST_ADDR, hello_world_7)
        num_attaches = 0
        logs = qd_manager.get_log()
        for log in logs:
            if u'SERVER' in log[0]:
                if "@attach" in log[2] and TEST_ADDR in log[2]:
                    num_attaches += 1

        self.assertTrue(num_attaches == 0)
    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}),
                ('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_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()