This is an automated email from the ASF dual-hosted git repository.

gmurthy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/qpid-dispatch.git


The following commit(s) were added to refs/heads/master by this push:
     new 37aef86  DISPATCH-1453 - Fix the code so that a correct error message 
shows up when a tx sender attaches in the absence of a coordinated link route. 
This closes #602.
37aef86 is described below

commit 37aef86a9ac20f5925de955846dd001de117ed5a
Author: Ganesh Murthy <gmur...@apache.org>
AuthorDate: Mon Oct 28 14:51:24 2019 -0400

    DISPATCH-1453 - Fix the code so that a correct error message shows up when 
a tx sender attaches in the absence of a coordinated link route. This closes 
#602.
---
 .../modules/address_lookup_client/lookup_client.c  | 10 +--
 tests/system_tests_one_router.py                   | 80 +++++++++++++++++++++-
 2 files changed, 83 insertions(+), 7 deletions(-)

diff --git a/src/router_core/modules/address_lookup_client/lookup_client.c 
b/src/router_core/modules/address_lookup_client/lookup_client.c
index 214624b..6bed399 100644
--- a/src/router_core/modules/address_lookup_client/lookup_client.c
+++ b/src/router_core/modules/address_lookup_client/lookup_client.c
@@ -312,9 +312,6 @@ static qdr_address_t 
*qdr_lookup_terminus_address_CT(qdr_core_t       *core,
             *unavailable = true;
     }
 
-    if (qdr_terminus_is_coordinator(terminus))
-        *unavailable = false;
-
     if (!!addr && addr->core_endpoint != 0)
         *core_endpoint = true;
 
@@ -341,7 +338,11 @@ static void qdr_link_react_to_first_attach_CT(qdr_core_t   
    *core,
     if (core_endpoint) {
         qdrc_endpoint_do_bound_attach_CT(core, addr, link, source, target);
     }
-
+    else if (unavailable && qdr_terminus_is_coordinator(dir == QD_INCOMING ? 
target : source) && !addr) {
+        qdr_link_outbound_detach_CT(core, link, 0, 
QDR_CONDITION_COORDINATOR_PRECONDITION_FAILED, true);
+        qdr_terminus_free(source);
+        qdr_terminus_free(target);
+    }
     else if (unavailable) {
         qdr_link_outbound_detach_CT(core, link, 
qdr_error(QD_AMQP_COND_NOT_FOUND, "Node not found"), 0, true);
         qdr_terminus_free(source);
@@ -672,7 +673,6 @@ static uint64_t on_reply(qdr_core_t    *core,
             // The address is for a link route, but there are no destinations 
upstream.  Fail with no-route.
             //
             qdr_link_outbound_detach_CT(core, link, 0, 
QDR_CONDITION_NO_ROUTE_TO_DESTINATION, true);
-
         else
             //
             // The address is for a link route and there are destinations 
upstream.  Directly forward the attach.
diff --git a/tests/system_tests_one_router.py b/tests/system_tests_one_router.py
index 521113f..1840229 100644
--- a/tests/system_tests_one_router.py
+++ b/tests/system_tests_one_router.py
@@ -24,7 +24,7 @@ from __future__ import print_function
 
 from proton import Condition, Message, Delivery, Url, symbol, Timeout
 from system_test import TestCase, Qdrouterd, main_module, TIMEOUT, DIR, Process
-from system_test import unittest
+from system_test import unittest, QdManager
 from proton.handlers import MessagingHandler, TransactionHandler
 from proton.reactor import Container, AtMostOnce, AtLeastOnce, 
DynamicNodeProperties, LinkOption, ApplicationEvent, EventInjector
 from proton.utils import BlockingConnection, SyncRequestResponse
@@ -503,7 +503,6 @@ class OneRouterTest(TestCase):
         self.assertEqual(None, test.error)
 
 
-
 class Entity(object):
     def __init__(self, status_code, status_description, attrs):
         self.status_code        = status_code
@@ -3160,6 +3159,83 @@ class UnsettledLargeMessageTest(MessagingHandler):
             self.receiver.close()
             self.recv_conn.close()
 
+class OneRouterUnavailableCoordinatorTest(TestCase):
+    @classmethod
+    def setUpClass(cls):
+        super(OneRouterUnavailableCoordinatorTest, cls).setUpClass()
+        name = "test-router"
+        OneRouterTest.listen_port = cls.tester.get_port()
+        config = Qdrouterd.Config([
+            ('router', {'mode': 'standalone', 'id': 'QDR',  
'defaultDistribution': 'unavailable'}),
+            ('listener', {'port': cls.tester.get_port() }),
+            ('address', {'prefix': 'closest', 'distribution': 'closest'}),
+            ('address', {'prefix': 'balanced', 'distribution': 'balanced'}),
+            ('address', {'prefix': 'multicast', 'distribution': 'multicast'}),
+        ])
+        cls.router = cls.tester.qdrouterd(name, config)
+        cls.router.wait_ready()
+        cls.address = cls.router.addresses[0]
+
+    def test_46_coordinator_linkroute_unavailable_DISPATCH_1453(self):
+        # The defaultDistribution on the router is unavailable. We try to 
connect a tx sender
+        # to make sure a good detailed message saying "the link route to a 
coordinator must be
+        # configured" is sent back.
+        test = RejectCoordinatorGoodMessageTest(self.address)
+        test.run()
+        self.assertTrue(test.passed)
+
+    def test_47_coordinator_linkroute_available_DISPATCH_1453(self):
+        # The defaultDistribution on the router is unavailable. We create a 
link route with $coordinator address
+        # The link route is not attached to any broker. When the attach comes 
in, the reject message must be
+        # condition=:"qd:no-route-to-dest", description="No route to the 
destination node"
+        COORDINATOR = "$coordinator"
+        long_type = 'org.apache.qpid.dispatch.router.config.linkRoute'
+        qd_manager = QdManager(self, address=self.address)
+        args = {"prefix": COORDINATOR, "connection": "broker", "dir": "in"}
+        qd_manager.create(long_type, args)
+        link_route_created = False
+
+        # Verify that the link route was created by querying for it.
+        outs = qd_manager.query(long_type)[0]
+        if outs:
+            try:
+                if outs['prefix'] == COORDINATOR:
+                    link_route_created = True
+            except:
+                pass
+
+        self.assertTrue(link_route_created)
+
+        # We have verified that the link route has been created but there is 
no broker connections.
+        # Now let's try to open a transaction. We should get a no route to 
destination error
+        test = RejectCoordinatorGoodMessageTest(self.address, 
link_route_present=True)
+        test.run()
+        self.assertTrue(test.passed)
+
+
+class RejectCoordinatorGoodMessageTest(RejectCoordinatorTest):
+    def __init__(self, url, link_route_present=False):
+        super(RejectCoordinatorGoodMessageTest, self).__init__(url)
+        self.link_route_present = link_route_present
+        self.error_with_link_route = "No route to the destination node"
+
+    def on_link_error(self, event):
+        link = event.link
+        # If the link name is 'txn-ctrl' and there is a link error and it 
matches self.error, then we know
+        # that the router has rejected the link because it cannot coordinate 
transactions itself
+        if link.name == "txn-ctrl":
+            if self.link_route_present:
+                if link.remote_condition.description == 
self.error_with_link_route and link.remote_condition.name == 
'qd:no-route-to-dest':
+                    self.link_error = True
+            else:
+                if link.remote_condition.description == self.error and 
link.remote_condition.name == 'amqp:precondition-failed':
+                    self.link_error = True
+
+            self.check_if_done()
+
+    def run(self):
+        Container(self).run()
+
 
 class Q2HoldoffDropTest(MessagingHandler):
     """


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org
For additional commands, e-mail: commits-h...@qpid.apache.org

Reply via email to