You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by kp...@apache.org on 2012/08/27 17:40:45 UTC

svn commit: r1377715 [9/12] - in /qpid/branches/asyncstore: ./ bin/ cpp/ cpp/docs/api/ cpp/examples/old_api/tradedemo/ cpp/include/qmf/engine/ cpp/include/qpid/client/ cpp/src/ cpp/src/qmf/engine/ cpp/src/qpid/acl/ cpp/src/qpid/asyncStore/ cpp/src/qpid...

Modified: qpid/branches/asyncstore/cpp/src/tests/acl.py
URL: http://svn.apache.org/viewvc/qpid/branches/asyncstore/cpp/src/tests/acl.py?rev=1377715&r1=1377714&r2=1377715&view=diff
==============================================================================
--- qpid/branches/asyncstore/cpp/src/tests/acl.py (original)
+++ qpid/branches/asyncstore/cpp/src/tests/acl.py Mon Aug 27 15:40:33 2012
@@ -119,6 +119,7 @@ class ACLTests(TestBase010):
     def LookupPublish(self, userName, exchName, keyName, expectedResult):
         result = self.acl_lookupPublish(userName, exchName, keyName)
         if (result['result'] != expectedResult):
+            suffix = ', [ERROR: Expected= ' + expectedResult
             if (result['result'] is None):
                 suffix = suffix + ', Exception= ' + result['text'] + ']'
             else:
@@ -1703,6 +1704,546 @@ class ACLTests(TestBase010):
             result = None
 
 
+   #=====================================
+   # User name substitution
+   #=====================================
+
+    def test_user_name_substitution(self):
+        """
+        Test name substitution internals, limits, and edge cases.
+        """
+        aclf = self.get_acl_file()
+        aclf.write('# begin hack alert: allow anonymous to access the lookup debug functions\n')
+        aclf.write('acl allow-log anonymous create  queue\n')
+        aclf.write('acl allow-log anonymous all     exchange name=qmf.*\n')
+        aclf.write('acl allow-log anonymous all     exchange name=amq.direct\n')
+        aclf.write('acl allow-log anonymous all     exchange name=qpid.management\n')
+        aclf.write('acl allow-log anonymous access  method   name=*\n')
+        aclf.write('# end hack alert\n')
+        aclf.write('acl allow all create queue    name=tmp-${userdomain}\n')
+        aclf.write('acl allow all create queue    name=${userdomain}-tmp\n')
+        aclf.write('acl allow all create queue    name=tmp-${userdomain}-tmp\n')
+        aclf.write('acl allow all create queue    name=tmp-${userdomain}-tmp-${userdomain}\n')
+        aclf.write('acl allow all create  queue    name=temp0-${userdomain}\n')
+        aclf.write('acl allow all access  queue    name=temp0-${userdomain}\n')
+        aclf.write('acl allow all purge   queue    name=temp0-${userdomain}\n')
+        aclf.write('acl allow all consume queue    name=temp0-${userdomain}\n')
+        aclf.write('acl allow all delete  queue    name=temp0-${userdomain}\n')
+        aclf.write('acl allow all create  exchange name=temp0-${userdomain}\n')
+        aclf.write('acl allow all access  exchange name=temp0-${userdomain}\n')
+        aclf.write('acl allow all bind    exchange name=temp0-${userdomain}\n')
+        aclf.write('acl allow all unbind  exchange name=temp0-${userdomain}\n')
+        aclf.write('acl allow all delete  exchange name=temp0-${userdomain}\n')
+        aclf.write('acl allow all publish exchange name=temp0-${userdomain}\n')
+
+        aclf.write('acl allow all   publish exchange name=X routingkey=${userdomain}.cd.e\n')
+        aclf.write('acl allow all   publish exchange name=X routingkey=a.*.${userdomain}\n')
+        aclf.write('acl allow all   publish exchange name=X routingkey=b.#.${userdomain}\n')
+        aclf.write('acl allow all   publish exchange name=X routingkey=*.${userdomain}.#.y\n')
+
+        aclf.write('acl allow all   create  queue    name=user-${user}\n')
+        aclf.write('acl allow all   publish exchange name=U routingkey=${user}.cd.e\n')
+        aclf.write('acl allow all   publish exchange name=U routingkey=a.*.${user}\n')
+        aclf.write('acl allow all   publish exchange name=U routingkey=b.#.${user}\n')
+        aclf.write('acl allow all   publish exchange name=U routingkey=*.${user}.#.y\n')
+
+        aclf.write('acl allow all   create  queue    name=domain-${domain}\n')
+        aclf.write('acl allow all   publish exchange name=D routingkey=${domain}.cd.e\n')
+        aclf.write('acl allow all   publish exchange name=D routingkey=a.*.${domain}\n')
+        aclf.write('acl allow all   publish exchange name=D routingkey=b.#.${domain}\n')
+        aclf.write('acl allow all   publish exchange name=D routingkey=*.${domain}.#.y\n')
+
+        # Resolving ${user}_${domain} into ${userdomain} works for everything but routing keys
+        aclf.write('acl allow all   create  queue    name=mixed-OK-${user}_${domain}\n')
+        # For routing keys ${user}_${domain} will be parsed into ${userdomain}.
+        # Routing keys not be found when the rule specifies ${user}_${domain}.
+        aclf.write('acl allow all   publish exchange name=NOGO routingkey=${user}_${domain}.cd.e\n')
+        # This works since it is does not conflict with ${userdomain}
+        aclf.write('acl allow all   publish exchange name=OK   routingkey=${user}___${domain}.cd.e\n')
+
+        aclf.write('acl deny-log all all\n')
+        aclf.close()
+
+        result = self.reload_acl()
+        if (result):
+            self.fail(result)
+
+        self.Lookup("alice@QPID",   "create", "queue", "tmp-alice_QPID",              {}, "allow")
+        self.Lookup("bob@QPID",     "create", "queue", "bob_QPID-tmp",                {}, "allow")
+        self.Lookup("charlie@QPID", "create", "queue", "tmp-charlie_QPID-tmp",        {}, "allow")
+        self.Lookup("dave@QPID",    "create", "queue", "tmp-dave_QPID-tmp-dave_QPID", {}, "allow")
+        self.Lookup("ed@BIG.COM",   "create", "queue", "tmp-ed_BIG_COM",              {}, "allow")
+        self.Lookup("c.e.r@BIG.GER.COM", "create", "queue", "tmp-c_e_r_BIG_GER_COM",  {}, "allow")
+        self.Lookup("c@",           "create", "queue", "tmp-c_",                      {}, "allow")
+        self.Lookup("someuser",     "create", "queue", "tmp-someuser",                {}, "allow")
+
+        self.Lookup("alice@QPID",   "create", "queue", "tmp-${user}",                 {}, "deny-log")
+
+        self.Lookup("bob@QPID",     "create", "exchange", "temp0-bob_QPID", {}, "allow")
+        self.Lookup("bob@QPID",     "access", "exchange", "temp0-bob_QPID", {}, "allow")
+        self.Lookup("bob@QPID",     "bind",   "exchange", "temp0-bob_QPID", {}, "allow")
+        self.Lookup("bob@QPID",     "unbind", "exchange", "temp0-bob_QPID", {}, "allow")
+        self.Lookup("bob@QPID",     "delete", "exchange", "temp0-bob_QPID", {}, "allow")
+        self.LookupPublish("bob@QPID", "temp0-bob_QPID", "x", "allow")
+
+        self.Lookup("bob@QPID",     "create",  "queue", "temp0-bob_QPID", {}, "allow")
+        self.Lookup("bob@QPID",     "access",  "queue", "temp0-bob_QPID", {}, "allow")
+        self.Lookup("bob@QPID",     "purge",   "queue", "temp0-bob_QPID", {}, "allow")
+        self.Lookup("bob@QPID",     "consume", "queue", "temp0-bob_QPID", {}, "allow")
+        self.Lookup("bob@QPID",     "delete",  "queue", "temp0-bob_QPID", {}, "allow")
+
+        self.Lookup("alice@QPID",   "access",  "queue", "temp0-bob_QPID", {}, "deny-log")
+
+        #                                  aclKey: "${userdomain}.cd.e"
+        self.LookupPublish("uPlain1@COMPANY", "X", "uPlain1_COMPANY.cd.e",   "allow")
+        #                                  aclKey: "a.*.${userdomain}"
+        self.LookupPublish("uStar1@COMPANY", "X", "a.xx.uStar1_COMPANY",   "allow")
+        self.LookupPublish("uStar1@COMPANY", "X", "a.b",                   "deny-log")
+        #                                  aclKey: "b.#.${userdomain}"
+        self.LookupPublish("uHash1@COMPANY", "X", "b.uHash1_COMPANY",         "allow")
+        self.LookupPublish("uHash1@COMPANY", "X", "b.x.uHash1_COMPANY",       "allow")
+        self.LookupPublish("uHash1@COMPANY", "X", "b..x.y.zz.uHash1_COMPANY", "allow")
+        self.LookupPublish("uHash1@COMPANY", "X", "b.uHash1_COMPANY.",        "deny-log")
+        self.LookupPublish("uHash1@COMPANY", "X", "q.x.uHash1_COMPANY",       "deny-log")
+        #                                  aclKey: "*.${userdomain}.#.y"
+        self.LookupPublish("uMixed1@COMPANY", "X", "a.uMixed1_COMPANY.y",          "allow")
+        self.LookupPublish("uMixed1@COMPANY", "X", "a.uMixed1_COMPANY.p.qq.y",     "allow")
+        self.LookupPublish("uMixed1@COMPANY", "X", "a.a.uMixed1_COMPANY.y",        "deny-log")
+        self.LookupPublish("uMixed1@COMPANY", "X", "aa.uMixed1_COMPANY.b.c",       "deny-log")
+        self.LookupPublish("uMixed1@COMPANY.COM", "X", "a.uMixed1_COMPANY_COM.y",  "allow")
+
+
+        self.Lookup("bob@QPID",     "create", "queue", "user-bob",                {}, "allow")
+        #                                  aclKey: "${user}.cd.e"
+        self.LookupPublish("uPlain1@COMPANY", "U", "uPlain1.cd.e",   "allow")
+        #                                  aclKey: "a.*.${user}"
+        self.LookupPublish("uStar1@COMPANY", "U", "a.xx.uStar1",   "allow")
+        self.LookupPublish("uStar1@COMPANY", "U", "a.b",                   "deny-log")
+        #                                  aclKey: "b.#.${user}"
+        self.LookupPublish("uHash1@COMPANY", "U", "b.uHash1",         "allow")
+        self.LookupPublish("uHash1@COMPANY", "U", "b.x.uHash1",       "allow")
+        self.LookupPublish("uHash1@COMPANY", "U", "b..x.y.zz.uHash1", "allow")
+        self.LookupPublish("uHash1@COMPANY", "U", "b.uHash1.",        "deny-log")
+        self.LookupPublish("uHash1@COMPANY", "U", "q.x.uHash1",       "deny-log")
+        #                                  aclKey: "*.${user}.#.y"
+        self.LookupPublish("uMixed1@COMPANY",     "U", "a.uMixed1.y",          "allow")
+        self.LookupPublish("uMixed1@COMPANY",     "U", "a.uMixed1.p.qq.y",     "allow")
+        self.LookupPublish("uMixed1@COMPANY",     "U", "a.a.uMixed1.y",        "deny-log")
+        self.LookupPublish("uMixed1@COMPANY",     "U", "aa.uMixed1.b.c",       "deny-log")
+        self.LookupPublish("uMixed1@COMPANY.COM", "U", "a.uMixed1.y",          "allow")
+
+
+        self.Lookup("bob@QPID",     "create", "queue", "domain-QPID",                {}, "allow")
+        #                                  aclKey: "${domain}.cd.e"
+        self.LookupPublish("uPlain1@COMPANY", "D", "COMPANY.cd.e",         "allow")
+        #                                  aclKey: "a.*.${domain}"
+        self.LookupPublish("uStar1@COMPANY", "D", "a.xx.COMPANY",          "allow")
+        self.LookupPublish("uStar1@COMPANY", "D", "a.b",                   "deny-log")
+        #                                  aclKey: "b.#.${domain}"
+        self.LookupPublish("uHash1@COMPANY", "D", "b.COMPANY",             "allow")
+        self.LookupPublish("uHash1@COMPANY", "D", "b.x.COMPANY",           "allow")
+        self.LookupPublish("uHash1@COMPANY", "D", "b..x.y.zz.COMPANY",     "allow")
+        self.LookupPublish("uHash1@COMPANY", "D", "b.COMPANY.",            "deny-log")
+        self.LookupPublish("uHash1@COMPANY", "D", "q.x.COMPANY",           "deny-log")
+        #                                  aclKey: "*.${domain}.#.y"
+        self.LookupPublish("uMixed1@COMPANY", "D", "a.COMPANY.y",          "allow")
+        self.LookupPublish("uMixed1@COMPANY", "D", "a.COMPANY.p.qq.y",     "allow")
+        self.LookupPublish("uMixed1@COMPANY", "D", "a.a.COMPANY.y",        "deny-log")
+        self.LookupPublish("uMixed1@COMPANY", "D", "aa.COMPANY.b.c",       "deny-log")
+        self.LookupPublish("uMixed1@COMPANY.COM", "D", "a.COMPANY_COM.y",  "allow")
+
+        self.Lookup("uPlain1@COMPANY", "create", "queue", "mixed-OK-uPlain1_COMPANY", {}, "allow")
+        self.LookupPublish("uPlain1@COMPANY", "NOGO", "uPlain1_COMPANY.cd.e",             "deny-log")
+        self.LookupPublish("uPlain1@COMPANY", "OK",   "uPlain1___COMPANY.cd.e",           "allow")
+
+
+   #=====================================
+   # User name substitution details
+   #=====================================
+   #  User name substitution allows for three flavors of keyword in the Acl file.
+   #  Given a user name of bob.user@QPID.COM the keywords are normalized and resolve as follows:
+   #   ${userdomain} - bob_user_QPID_COM
+   #   ${user}       - bob_user
+   #   ${domain}     - QPID_COM
+   #
+   # The following substitution tests are very similar but differ in the flavor of keyword used
+   # in the rules. The tests results using the different keywords differ slightly in how permissive
+   # the rules become.
+   #   ${userdomain} limits access to one authenticated user
+   #   ${user}       limits access to a user name regardless of user's domain
+   #   ${domain}     limits access to a domain regardless of user name
+   #
+
+    def test_user_name_substitution_userdomain(self):
+        """
+        Test a setup where users can create, bind, and publish to a main exchange and queue.
+        Allow access to a single alternate exchange and queue.
+        """
+        aclf = self.get_acl_file()
+        aclf.write('# begin hack alert: allow anonymous to access the lookup debug functions\n')
+        aclf.write('acl allow-log anonymous create  queue\n')
+        aclf.write('acl allow-log anonymous all     exchange name=qmf.*\n')
+        aclf.write('acl allow-log anonymous all     exchange name=amq.direct\n')
+        aclf.write('acl allow-log anonymous all     exchange name=qpid.management\n')
+        aclf.write('acl allow-log anonymous access  method   name=*\n')
+        aclf.write('# end hack alert\n')
+        # Create primary queue and exchange:
+        #   allow predefined alternate
+        #   deny  any other alternate
+        #   allow no alternate
+        aclf.write('acl allow all create  queue    name=${userdomain}-work alternate=${userdomain}-work2\n')
+        aclf.write('acl deny  all create  queue    name=${userdomain}-work alternate=*\n')
+        aclf.write('acl allow all create  queue    name=${userdomain}-work\n')
+        aclf.write('acl allow all create  exchange name=${userdomain}-work alternate=${userdomain}-work2\n')
+        aclf.write('acl deny  all create  exchange name=${userdomain}-work alternate=*\n')
+        aclf.write('acl allow all create  exchange name=${userdomain}-work\n')
+        # Create backup queue and exchange
+        #   Deny any alternate
+        aclf.write('acl deny  all create  queue    name=${userdomain}-work2 alternate=*\n')
+        aclf.write('acl allow all create  queue    name=${userdomain}-work2\n')
+        aclf.write('acl deny  all create  exchange name=${userdomain}-work2 alternate=*\n')
+        aclf.write('acl allow all create  exchange name=${userdomain}-work2\n')
+        # Bind/unbind primary exchange
+        #  Use only predefined routingkey and queuename
+        aclf.write('acl allow all bind    exchange name=${userdomain}-work routingkey=${userdomain} queuename=${userdomain}-work\n')
+        aclf.write('acl allow all unbind  exchange name=${userdomain}-work routingkey=${userdomain} queuename=${userdomain}-work\n')
+        # Bind/unbind backup exchange
+        #  Use only predefined routingkey and queuename
+        aclf.write('acl allow all bind    exchange name=${userdomain}-work2 routingkey=${userdomain} queuename=${userdomain}-work2\n')
+        aclf.write('acl allow all unbind  exchange name=${userdomain}-work2 routingkey=${userdomain} queuename=${userdomain}-work2\n')
+        # Access primary exchange
+        #  Use only predefined routingkey and queuename
+        aclf.write('acl allow all access  exchange name=${userdomain}-work routingkey=${userdomain} queuename=${userdomain}-work\n')
+        # Access backup exchange
+        #  Use only predefined routingkey and queuename
+        aclf.write('acl allow all access  exchange name=${userdomain}-work2 routingkey=${userdomain} queuename=${userdomain}-work2\n')
+        # Publish primary exchange
+        #  Use only predefined routingkey
+        aclf.write('acl allow all publish exchange name=${userdomain}-work routingkey=${userdomain}\n')
+        # Publish backup exchange
+        #  Use only predefined routingkey
+        aclf.write('acl allow all publish exchange name=${userdomain}-work2 routingkey=${userdomain}\n')
+        # deny mode
+        aclf.write('acl deny all all\n')
+        aclf.close()
+
+        result = self.reload_acl()
+        if (result):
+            self.fail(result)
+
+        # create queues
+        self.Lookup("bob@QPID",     "create", "queue", "bob_QPID-work",    {},                             "allow")
+        self.Lookup("bob@QPID",     "create", "queue", "bob_QPID-work2",   {},                             "allow")
+        self.Lookup("bob@QPID",     "create", "queue", "joe_QPID-work",    {},                             "deny")
+        self.Lookup("bob@QPID",     "create", "queue", "joe_QPID-work2",   {},                             "deny")
+        self.Lookup("bob@QPID",     "create", "queue", "bob_QPID-work3",   {},                             "deny")
+        self.Lookup("bob@QPID",     "create", "queue", "bob_QPID-work",    {"alternate":"bob_QPID-work2"}, "allow")
+        self.Lookup("bob@QPID",     "create", "queue", "bob_QPID-work",    {"alternate":"joe_QPID-work2"}, "deny")
+        self.Lookup("bob@QPID",     "create", "queue", "bob_QPID-work2",   {"alternate":"someexchange"},   "deny")
+        # create exchanges
+        self.Lookup("bob@QPID",     "create", "exchange", "bob_QPID-work", {},                             "allow")
+        self.Lookup("bob@QPID",     "create", "exchange", "bob_QPID-work2",{},                             "allow")
+        self.Lookup("bob@QPID",     "create", "exchange", "joe_QPID-work", {},                             "deny")
+        self.Lookup("bob@QPID",     "create", "exchange", "joe_QPID-work2",{},                             "deny")
+        self.Lookup("bob@QPID",     "create", "exchange", "bob_QPID-work3",{},                             "deny")
+        self.Lookup("bob@QPID",     "create", "exchange", "bob_QPID-work", {"alternate":"bob_QPID-work2"}, "allow")
+        self.Lookup("bob@QPID",     "create", "exchange", "bob_QPID-work2",{"alternate":"someexchange"},   "deny")
+        # bind/unbind/access
+        self.Lookup("bob@QPID", "bind", "exchange", "bob_QPID-work", {},                                                     "deny")
+        self.Lookup("bob@QPID", "bind", "exchange", "bob_QPID-work", {"routingkey":"bob_QPID"},                              "deny")
+        self.Lookup("bob@QPID", "bind", "exchange", "bob_QPID-work", {                         "queuename":"bob_QPID-work"}, "deny")
+        self.Lookup("bob@QPID", "bind", "exchange", "bob_QPID-work", {"routingkey":"bob_QPID", "queuename":"bob_QPID-work"}, "allow")
+        self.Lookup("bob@QPID", "bind", "exchange", "joe_QPID-work", {"routingkey":"bob_QPID", "queuename":"bob_QPID-work"}, "deny")
+        self.Lookup("bob@QPID", "bind", "exchange", "bob_QPID-work", {"routingkey":"joe_QPID", "queuename":"bob_QPID-work"}, "deny")
+        self.Lookup("bob@QPID", "bind", "exchange", "bob_QPID-work", {"routingkey":"bob_QPID", "queuename":"joe_QPID-work"}, "deny")
+
+        self.Lookup("bob@QPID", "bind", "exchange", "bob_QPID-work2", {},                                                      "deny")
+        self.Lookup("bob@QPID", "bind", "exchange", "bob_QPID-work2", {"routingkey":"bob_QPID"},                               "deny")
+        self.Lookup("bob@QPID", "bind", "exchange", "bob_QPID-work2", {                         "queuename":"bob_QPID-work2"}, "deny")
+        self.Lookup("bob@QPID", "bind", "exchange", "bob_QPID-work2", {"routingkey":"bob_QPID", "queuename":"bob_QPID-work2"}, "allow")
+        self.Lookup("bob@QPID", "bind", "exchange", "joe_QPID-work2", {"routingkey":"bob_QPID", "queuename":"bob_QPID-work2"}, "deny")
+        self.Lookup("bob@QPID", "bind", "exchange", "bob_QPID-work2", {"routingkey":"joe_QPID", "queuename":"bob_QPID-work2"}, "deny")
+        self.Lookup("bob@QPID", "bind", "exchange", "bob_QPID-work2", {"routingkey":"bob_QPID", "queuename":"joe_QPID-work2"}, "deny")
+
+        self.Lookup("bob@QPID", "unbind", "exchange", "bob_QPID-work", {},                                                     "deny")
+        self.Lookup("bob@QPID", "unbind", "exchange", "bob_QPID-work", {"routingkey":"bob_QPID"},                              "deny")
+        self.Lookup("bob@QPID", "unbind", "exchange", "bob_QPID-work", {                         "queuename":"bob_QPID-work"}, "deny")
+        self.Lookup("bob@QPID", "unbind", "exchange", "bob_QPID-work", {"routingkey":"bob_QPID", "queuename":"bob_QPID-work"}, "allow")
+        self.Lookup("bob@QPID", "unbind", "exchange", "joe_QPID-work", {"routingkey":"bob_QPID", "queuename":"bob_QPID-work"}, "deny")
+        self.Lookup("bob@QPID", "unbind", "exchange", "bob_QPID-work", {"routingkey":"joe_QPID", "queuename":"bob_QPID-work"}, "deny")
+        self.Lookup("bob@QPID", "unbind", "exchange", "bob_QPID-work", {"routingkey":"bob_QPID", "queuename":"joe_QPID-work"}, "deny")
+
+        self.Lookup("bob@QPID", "unbind", "exchange", "bob_QPID-work2", {},                                                      "deny")
+        self.Lookup("bob@QPID", "unbind", "exchange", "bob_QPID-work2", {"routingkey":"bob_QPID"},                               "deny")
+        self.Lookup("bob@QPID", "unbind", "exchange", "bob_QPID-work2", {                         "queuename":"bob_QPID-work2"}, "deny")
+        self.Lookup("bob@QPID", "unbind", "exchange", "bob_QPID-work2", {"routingkey":"bob_QPID", "queuename":"bob_QPID-work2"}, "allow")
+        self.Lookup("bob@QPID", "unbind", "exchange", "joe_QPID-work2", {"routingkey":"bob_QPID", "queuename":"bob_QPID-work2"}, "deny")
+        self.Lookup("bob@QPID", "unbind", "exchange", "bob_QPID-work2", {"routingkey":"joe_QPID", "queuename":"bob_QPID-work2"}, "deny")
+        self.Lookup("bob@QPID", "unbind", "exchange", "bob_QPID-work2", {"routingkey":"bob_QPID", "queuename":"joe_QPID-work2"}, "deny")
+
+        self.Lookup("bob@QPID", "access", "exchange", "bob_QPID-work", {},                                                     "deny")
+        self.Lookup("bob@QPID", "access", "exchange", "bob_QPID-work", {"routingkey":"bob_QPID"},                              "deny")
+        self.Lookup("bob@QPID", "access", "exchange", "bob_QPID-work", {                         "queuename":"bob_QPID-work"}, "deny")
+        self.Lookup("bob@QPID", "access", "exchange", "bob_QPID-work", {"routingkey":"bob_QPID", "queuename":"bob_QPID-work"}, "allow")
+        self.Lookup("bob@QPID", "access", "exchange", "joe_QPID-work", {"routingkey":"bob_QPID", "queuename":"bob_QPID-work"}, "deny")
+        self.Lookup("bob@QPID", "access", "exchange", "bob_QPID-work", {"routingkey":"joe_QPID", "queuename":"bob_QPID-work"}, "deny")
+        self.Lookup("bob@QPID", "access", "exchange", "bob_QPID-work", {"routingkey":"bob_QPID", "queuename":"joe_QPID-work"}, "deny")
+
+        self.Lookup("bob@QPID", "access", "exchange", "bob_QPID-work2", {},                                                      "deny")
+        self.Lookup("bob@QPID", "access", "exchange", "bob_QPID-work2", {"routingkey":"bob_QPID"},                               "deny")
+        self.Lookup("bob@QPID", "access", "exchange", "bob_QPID-work2", {                         "queuename":"bob_QPID-work2"}, "deny")
+        self.Lookup("bob@QPID", "access", "exchange", "bob_QPID-work2", {"routingkey":"bob_QPID", "queuename":"bob_QPID-work2"}, "allow")
+        self.Lookup("bob@QPID", "access", "exchange", "joe_QPID-work2", {"routingkey":"bob_QPID", "queuename":"bob_QPID-work2"}, "deny")
+        self.Lookup("bob@QPID", "access", "exchange", "bob_QPID-work2", {"routingkey":"joe_QPID", "queuename":"bob_QPID-work2"}, "deny")
+        self.Lookup("bob@QPID", "access", "exchange", "bob_QPID-work2", {"routingkey":"bob_QPID", "queuename":"joe_QPID-work2"}, "deny")
+        # publish
+        self.LookupPublish("bob@QPID", "bob_QPID-work",  "bob_QPID",        "allow")
+        self.LookupPublish("bob@QPID", "bob_QPID-work2", "bob_QPID",        "allow")
+        self.LookupPublish("bob@QPID", "joe_QPID-work",  "bob_QPID",        "deny")
+        self.LookupPublish("bob@QPID", "joe_QPID-work2", "bob_QPID",        "deny")
+        self.LookupPublish("bob@QPID", "bob_QPID-work",  "joe_QPID",        "deny")
+        self.LookupPublish("bob@QPID", "bob_QPID-work2", "joe_QPID",        "deny")
+
+
+    def test_user_name_substitution_user(self):
+        """
+        Test a setup where users can create, bind, and publish to a main exchange and queue.
+        Allow access to a single backup exchange and queue.
+        """
+        aclf = self.get_acl_file()
+        aclf.write('# begin hack alert: allow anonymous to access the lookup debug functions\n')
+        aclf.write('acl allow-log anonymous create  queue\n')
+        aclf.write('acl allow-log anonymous all     exchange name=qmf.*\n')
+        aclf.write('acl allow-log anonymous all     exchange name=amq.direct\n')
+        aclf.write('acl allow-log anonymous all     exchange name=qpid.management\n')
+        aclf.write('acl allow-log anonymous access  method   name=*\n')
+        aclf.write('# end hack alert\n')
+        # Create primary queue and exchange
+        #   allow predefined alternate
+        #   deny  any other alternate
+        #   allow no alternate
+        aclf.write('acl allow all create  queue    name=${user}-work alternate=${user}-work2\n')
+        aclf.write('acl deny  all create  queue    name=${user}-work alternate=*\n')
+        aclf.write('acl allow all create  queue    name=${user}-work\n')
+        aclf.write('acl allow all create  exchange name=${user}-work alternate=${user}-work2\n')
+        aclf.write('acl deny  all create  exchange name=${user}-work alternate=*\n')
+        aclf.write('acl allow all create  exchange name=${user}-work\n')
+        # Create backup queue and exchange
+        #   Deny any alternate
+        aclf.write('acl deny  all create  queue    name=${user}-work2 alternate=*\n')
+        aclf.write('acl allow all create  queue    name=${user}-work2\n')
+        aclf.write('acl deny  all create  exchange name=${user}-work2 alternate=*\n')
+        aclf.write('acl allow all create  exchange name=${user}-work2\n')
+        # Bind/unbind primary exchange
+        #  Use only predefined routingkey and queuename
+        aclf.write('acl allow all bind    exchange name=${user}-work routingkey=${user} queuename=${user}-work\n')
+        aclf.write('acl allow all unbind  exchange name=${user}-work routingkey=${user} queuename=${user}-work\n')
+        # Bind/unbind backup exchange
+        #  Use only predefined routingkey and queuename
+        aclf.write('acl allow all bind    exchange name=${user}-work2 routingkey=${user} queuename=${user}-work2\n')
+        aclf.write('acl allow all unbind  exchange name=${user}-work2 routingkey=${user} queuename=${user}-work2\n')
+        # Access primary exchange
+        #  Use only predefined routingkey and queuename
+        aclf.write('acl allow all access  exchange name=${user}-work routingkey=${user} queuename=${user}-work\n')
+        # Access backup exchange
+        #  Use only predefined routingkey and queuename
+        aclf.write('acl allow all access  exchange name=${user}-work2 routingkey=${user} queuename=${user}-work2\n')
+        # Publish primary exchange
+        #  Use only predefined routingkey
+        aclf.write('acl allow all publish exchange name=${user}-work routingkey=${user}\n')
+        # Publish backup exchange
+        #  Use only predefined routingkey
+        aclf.write('acl allow all publish exchange name=${user}-work2 routingkey=${user}\n')
+        # deny mode
+        aclf.write('acl deny all all\n')
+        aclf.close()
+
+        result = self.reload_acl()
+        if (result):
+            self.fail(result)
+
+        # create queues
+        self.Lookup("bob@QPID",     "create", "queue", "bob-work",    {},                          "allow")
+        self.Lookup("bob@QPID",     "create", "queue", "bob-work2",   {},                          "allow")
+        self.Lookup("bob@QPID",     "create", "queue", "joe-work",    {},                          "deny")
+        self.Lookup("bob@QPID",     "create", "queue", "joe-work2",   {},                          "deny")
+        self.Lookup("bob@QPID",     "create", "queue", "bob-work3",   {},                          "deny")
+        self.Lookup("bob@QPID",     "create", "queue", "bob-work",    {"alternate":"bob-work2"},   "allow")
+        self.Lookup("bob@QPID",     "create", "queue", "bob-work",    {"alternate":"joe-work2"},   "deny")
+        self.Lookup("bob@QPID",     "create", "queue", "bob-work2",   {"alternate":"someexchange"},"deny")
+        # create exchanges
+        self.Lookup("bob@QPID",     "create", "exchange", "bob-work", {},                          "allow")
+        self.Lookup("bob@QPID",     "create", "exchange", "bob-work2",{},                          "allow")
+        self.Lookup("bob@QPID",     "create", "exchange", "joe-work", {},                          "deny")
+        self.Lookup("bob@QPID",     "create", "exchange", "joe-work2",{},                          "deny")
+        self.Lookup("bob@QPID",     "create", "exchange", "bob-work3",{},                          "deny")
+        self.Lookup("bob@QPID",     "create", "exchange", "bob-work", {"alternate":"bob-work2"},   "allow")
+        self.Lookup("bob@QPID",     "create", "exchange", "bob-work2",{"alternate":"someexchange"},"deny")
+        # bind/unbind/access
+        self.Lookup("bob@QPID", "bind", "exchange", "bob-work", {},                                           "deny")
+        self.Lookup("bob@QPID", "bind", "exchange", "bob-work", {"routingkey":"bob"},                         "deny")
+        self.Lookup("bob@QPID", "bind", "exchange", "bob-work", {                    "queuename":"bob-work"}, "deny")
+        self.Lookup("bob@QPID", "bind", "exchange", "bob-work", {"routingkey":"bob", "queuename":"bob-work"}, "allow")
+        self.Lookup("bob@QPID", "bind", "exchange", "joe-work", {"routingkey":"bob", "queuename":"bob-work"}, "deny")
+        self.Lookup("bob@QPID", "bind", "exchange", "bob-work", {"routingkey":"joe", "queuename":"bob-work"}, "deny")
+        self.Lookup("bob@QPID", "bind", "exchange", "bob-work", {"routingkey":"bob", "queuename":"joe-work"}, "deny")
+
+        self.Lookup("bob@QPID", "bind", "exchange", "bob-work2", {},                                            "deny")
+        self.Lookup("bob@QPID", "bind", "exchange", "bob-work2", {"routingkey":"bob"},                          "deny")
+        self.Lookup("bob@QPID", "bind", "exchange", "bob-work2", {                    "queuename":"bob-work2"}, "deny")
+        self.Lookup("bob@QPID", "bind", "exchange", "bob-work2", {"routingkey":"bob", "queuename":"bob-work2"}, "allow")
+        self.Lookup("bob@QPID", "bind", "exchange", "joe-work2", {"routingkey":"bob", "queuename":"bob-work2"}, "deny")
+        self.Lookup("bob@QPID", "bind", "exchange", "bob-work2", {"routingkey":"joe", "queuename":"bob-work2"}, "deny")
+        self.Lookup("bob@QPID", "bind", "exchange", "bob-work2", {"routingkey":"bob", "queuename":"joe-work2"}, "deny")
+
+        self.Lookup("bob@QPID", "unbind", "exchange", "bob-work", {},                                           "deny")
+        self.Lookup("bob@QPID", "unbind", "exchange", "bob-work", {"routingkey":"bob"},                         "deny")
+        self.Lookup("bob@QPID", "unbind", "exchange", "bob-work", {                    "queuename":"bob-work"}, "deny")
+        self.Lookup("bob@QPID", "unbind", "exchange", "bob-work", {"routingkey":"bob", "queuename":"bob-work"}, "allow")
+        self.Lookup("bob@QPID", "unbind", "exchange", "joe-work", {"routingkey":"bob", "queuename":"bob-work"}, "deny")
+        self.Lookup("bob@QPID", "unbind", "exchange", "bob-work", {"routingkey":"joe", "queuename":"bob-work"}, "deny")
+        self.Lookup("bob@QPID", "unbind", "exchange", "bob-work", {"routingkey":"bob", "queuename":"joe-work"}, "deny")
+
+        self.Lookup("bob@QPID", "unbind", "exchange", "bob-work2", {},                                            "deny")
+        self.Lookup("bob@QPID", "unbind", "exchange", "bob-work2", {"routingkey":"bob"},                          "deny")
+        self.Lookup("bob@QPID", "unbind", "exchange", "bob-work2", {                    "queuename":"bob-work2"}, "deny")
+        self.Lookup("bob@QPID", "unbind", "exchange", "bob-work2", {"routingkey":"bob", "queuename":"bob-work2"}, "allow")
+        self.Lookup("bob@QPID", "unbind", "exchange", "joe-work2", {"routingkey":"bob", "queuename":"bob-work2"}, "deny")
+        self.Lookup("bob@QPID", "unbind", "exchange", "bob-work2", {"routingkey":"joe", "queuename":"bob-work2"}, "deny")
+        self.Lookup("bob@QPID", "unbind", "exchange", "bob-work2", {"routingkey":"bob", "queuename":"joe-work2"}, "deny")
+
+        self.Lookup("bob@QPID", "access", "exchange", "bob-work", {},                                           "deny")
+        self.Lookup("bob@QPID", "access", "exchange", "bob-work", {"routingkey":"bob"},                         "deny")
+        self.Lookup("bob@QPID", "access", "exchange", "bob-work", {                    "queuename":"bob-work"}, "deny")
+        self.Lookup("bob@QPID", "access", "exchange", "bob-work", {"routingkey":"bob", "queuename":"bob-work"}, "allow")
+        self.Lookup("bob@QPID", "access", "exchange", "joe-work", {"routingkey":"bob", "queuename":"bob-work"}, "deny")
+        self.Lookup("bob@QPID", "access", "exchange", "bob-work", {"routingkey":"joe", "queuename":"bob-work"}, "deny")
+        self.Lookup("bob@QPID", "access", "exchange", "bob-work", {"routingkey":"bob", "queuename":"joe-work"}, "deny")
+
+        self.Lookup("bob@QPID", "access", "exchange", "bob-work2", {},                                            "deny")
+        self.Lookup("bob@QPID", "access", "exchange", "bob-work2", {"routingkey":"bob"},                          "deny")
+        self.Lookup("bob@QPID", "access", "exchange", "bob-work2", {                    "queuename":"bob-work2"}, "deny")
+        self.Lookup("bob@QPID", "access", "exchange", "bob-work2", {"routingkey":"bob", "queuename":"bob-work2"}, "allow")
+        self.Lookup("bob@QPID", "access", "exchange", "joe-work2", {"routingkey":"bob", "queuename":"bob-work2"}, "deny")
+        self.Lookup("bob@QPID", "access", "exchange", "bob-work2", {"routingkey":"joe", "queuename":"bob-work2"}, "deny")
+        self.Lookup("bob@QPID", "access", "exchange", "bob-work2", {"routingkey":"bob", "queuename":"joe-work2"}, "deny")
+        # publish
+        self.LookupPublish("bob@QPID", "bob-work",  "bob",        "allow")
+        self.LookupPublish("bob@QPID", "bob-work2", "bob",        "allow")
+        self.LookupPublish("bob@QPID", "joe-work",  "bob",        "deny")
+        self.LookupPublish("bob@QPID", "joe-work2", "bob",        "deny")
+        self.LookupPublish("bob@QPID", "bob-work",  "joe",        "deny")
+        self.LookupPublish("bob@QPID", "bob-work2", "joe",        "deny")
+
+
+    def test_user_name_substitution_domain(self):
+        """
+        Test a setup where users can create, bind, and publish to a main exchange and queue.
+        Allow access to a single backup exchange and queue.
+        """
+        aclf = self.get_acl_file()
+        aclf.write('# begin hack alert: allow anonymous to access the lookup debug functions\n')
+        aclf.write('acl allow-log anonymous create  queue\n')
+        aclf.write('acl allow-log anonymous all     exchange name=qmf.*\n')
+        aclf.write('acl allow-log anonymous all     exchange name=amq.direct\n')
+        aclf.write('acl allow-log anonymous all     exchange name=qpid.management\n')
+        aclf.write('acl allow-log anonymous access  method   name=*\n')
+        aclf.write('# end hack alert\n')
+        # Create primary queue and exchange
+        #   allow predefined alternate
+        #   deny  any other alternate
+        #   allow no alternate
+        aclf.write('acl allow all create  queue    name=${domain}-work alternate=${domain}-work2\n')
+        aclf.write('acl deny  all create  queue    name=${domain}-work alternate=*\n')
+        aclf.write('acl allow all create  queue    name=${domain}-work\n')
+        aclf.write('acl allow all create  exchange name=${domain}-work alternate=${domain}-work2\n')
+        aclf.write('acl deny  all create  exchange name=${domain}-work alternate=*\n')
+        aclf.write('acl allow all create  exchange name=${domain}-work\n')
+        # Create backup queue and exchange
+        #   Deny any alternate
+        aclf.write('acl deny  all create  queue    name=${domain}-work2 alternate=*\n')
+        aclf.write('acl allow all create  queue    name=${domain}-work2\n')
+        aclf.write('acl deny  all create  exchange name=${domain}-work2 alternate=*\n')
+        aclf.write('acl allow all create  exchange name=${domain}-work2\n')
+        # Bind/unbind primary exchange
+        #  Use only predefined routingkey and queuename
+        aclf.write('acl allow all bind    exchange name=${domain}-work routingkey=${domain} queuename=${domain}-work\n')
+        aclf.write('acl allow all unbind  exchange name=${domain}-work routingkey=${domain} queuename=${domain}-work\n')
+        # Bind/unbind backup exchange
+        #  Use only predefined routingkey and queuename
+        aclf.write('acl allow all bind    exchange name=${domain}-work2 routingkey=${domain} queuename=${domain}-work2\n')
+        aclf.write('acl allow all unbind  exchange name=${domain}-work2 routingkey=${domain} queuename=${domain}-work2\n')
+        # Access primary exchange
+        #  Use only predefined routingkey and queuename
+        aclf.write('acl allow all access  exchange name=${domain}-work routingkey=${domain} queuename=${domain}-work\n')
+        # Access backup exchange
+        #  Use only predefined routingkey and queuename
+        aclf.write('acl allow all access  exchange name=${domain}-work2 routingkey=${domain} queuename=${domain}-work2\n')
+        # Publish primary exchange
+        #  Use only predefined routingkey
+        aclf.write('acl allow all publish exchange name=${domain}-work routingkey=${domain}\n')
+        # Publish backup exchange
+        #  Use only predefined routingkey
+        aclf.write('acl allow all publish exchange name=${domain}-work2 routingkey=${domain}\n')
+        # deny mode
+        aclf.write('acl deny all all\n')
+        aclf.close()
+
+        result = self.reload_acl()
+        if (result):
+            self.fail(result)
+
+        # create queues
+        self.Lookup("bob@QPID",     "create", "queue", "QPID-work",    {},                            "allow")
+        self.Lookup("bob@QPID",     "create", "queue", "QPID-work2",   {},                            "allow")
+        self.Lookup("bob@QPID",     "create", "queue", "QPID-work3",   {},                            "deny")
+        self.Lookup("bob@QPID",     "create", "queue", "QPID-work",    {"alternate":"QPID-work2"},    "allow")
+        self.Lookup("bob@QPID",     "create", "queue", "QPID-work",    {"alternate":"bob_QPID-work2"},"deny")
+        self.Lookup("bob@QPID",     "create", "queue", "QPID-work",    {"alternate":"joe_QPID-work2"},"deny")
+        self.Lookup("bob@QPID",     "create", "queue", "QPID-work2",   {"alternate":"someexchange"},  "deny")
+        # create exchanges
+        self.Lookup("bob@QPID",     "create", "exchange", "QPID-work", {},                           "allow")
+        self.Lookup("bob@QPID",     "create", "exchange", "QPID-work2",{},                           "allow")
+        self.Lookup("bob@QPID",     "create", "exchange", "QPID-work3",{},                           "deny")
+        self.Lookup("bob@QPID",     "create", "exchange", "QPID-work", {"alternate":"QPID-work2"},   "allow")
+        self.Lookup("bob@QPID",     "create", "exchange", "QPID-work2",{"alternate":"someexchange"}, "deny")
+        # bind/unbind/access
+        self.Lookup("bob@QPID", "bind", "exchange", "QPID-work", {},                                             "deny")
+        self.Lookup("bob@QPID", "bind", "exchange", "QPID-work", {"routingkey":"QPID"},                          "deny")
+        self.Lookup("bob@QPID", "bind", "exchange", "QPID-work", {                     "queuename":"QPID-work"}, "deny")
+        self.Lookup("bob@QPID", "bind", "exchange", "QPID-work", {"routingkey":"QPID", "queuename":"QPID-work"}, "allow")
+
+        self.Lookup("bob@QPID", "bind", "exchange", "QPID-work2", {},                                              "deny")
+        self.Lookup("bob@QPID", "bind", "exchange", "QPID-work2", {"routingkey":"QPID"},                           "deny")
+        self.Lookup("bob@QPID", "bind", "exchange", "QPID-work2", {                     "queuename":"QPID-work2"}, "deny")
+        self.Lookup("bob@QPID", "bind", "exchange", "QPID-work2", {"routingkey":"QPID", "queuename":"QPID-work2"}, "allow")
+
+        self.Lookup("bob@QPID", "unbind", "exchange", "QPID-work", {},                                             "deny")
+        self.Lookup("bob@QPID", "unbind", "exchange", "QPID-work", {"routingkey":"QPID"},                          "deny")
+        self.Lookup("bob@QPID", "unbind", "exchange", "QPID-work", {                     "queuename":"QPID-work"}, "deny")
+        self.Lookup("bob@QPID", "unbind", "exchange", "QPID-work", {"routingkey":"QPID", "queuename":"QPID-work"}, "allow")
+
+        self.Lookup("bob@QPID", "unbind", "exchange", "QPID-work2", {},                                              "deny")
+        self.Lookup("bob@QPID", "unbind", "exchange", "QPID-work2", {"routingkey":"QPID"},                           "deny")
+        self.Lookup("bob@QPID", "unbind", "exchange", "QPID-work2", {                     "queuename":"QPID-work2"}, "deny")
+        self.Lookup("bob@QPID", "unbind", "exchange", "QPID-work2", {"routingkey":"QPID", "queuename":"QPID-work2"}, "allow")
+
+        self.Lookup("bob@QPID", "access", "exchange", "QPID-work", {},                                             "deny")
+        self.Lookup("bob@QPID", "access", "exchange", "QPID-work", {"routingkey":"QPID"},                          "deny")
+        self.Lookup("bob@QPID", "access", "exchange", "QPID-work", {                     "queuename":"QPID-work"}, "deny")
+        self.Lookup("bob@QPID", "access", "exchange", "QPID-work", {"routingkey":"QPID", "queuename":"QPID-work"}, "allow")
+
+        self.Lookup("bob@QPID", "access", "exchange", "QPID-work2", {},                                              "deny")
+        self.Lookup("bob@QPID", "access", "exchange", "QPID-work2", {"routingkey":"QPID"},                           "deny")
+        self.Lookup("bob@QPID", "access", "exchange", "QPID-work2", {                     "queuename":"QPID-work2"}, "deny")
+        self.Lookup("bob@QPID", "access", "exchange", "QPID-work2", {"routingkey":"QPID", "queuename":"QPID-work2"}, "allow")
+        # publish
+        self.LookupPublish("bob@QPID", "QPID-work",  "QPID",        "allow")
+        self.LookupPublish("bob@QPID", "QPID-work2", "QPID",        "allow")
+        self.LookupPublish("joe@QPID", "QPID-work",  "QPID",        "allow")
+        self.LookupPublish("joe@QPID", "QPID-work2", "QPID",        "allow")
+
+
 class BrokerAdmin:
     def __init__(self, broker, username=None, password=None):
         self.connection = qpid.messaging.Connection(broker)

Propchange: qpid/branches/asyncstore/cpp/src/tests/cluster_tests.py
------------------------------------------------------------------------------
  Merged /qpid/trunk/qpid/cpp/src/tests/cluster_tests.py:r1368652-1375508

Modified: qpid/branches/asyncstore/cpp/src/tests/ha_tests.py
URL: http://svn.apache.org/viewvc/qpid/branches/asyncstore/cpp/src/tests/ha_tests.py?rev=1377715&r1=1377714&r2=1377715&view=diff
==============================================================================
--- qpid/branches/asyncstore/cpp/src/tests/ha_tests.py (original)
+++ qpid/branches/asyncstore/cpp/src/tests/ha_tests.py Mon Aug 27 15:40:33 2012
@@ -111,9 +111,11 @@ class HaBroker(Broker):
     def wait_status(self, status):
         def try_get_status():
             # Ignore ConnectionError, the broker may not be up yet.
-            try: return self.ha_status() == status;
+            try:
+                self._status = self.ha_status()
+                return self._status == status;
             except ConnectionError: return False
-        assert retry(try_get_status, timeout=20), "%s status != %r"%(self, status)
+        assert retry(try_get_status, timeout=20), "%s %r != %r"%(self, self._status, status)
 
     # FIXME aconway 2012-05-01: do direct python call to qpid-config code.
     def qpid_config(self, args):
@@ -581,15 +583,7 @@ class ReplicationTests(BrokerTest):
         s = primary.connect().session().sender("q; {create:always, node:{x-declare:{arguments:{'qpid.policy_type':ring, 'qpid.max_count':5, 'qpid.priorities':10}}}}")
         priorities = [8,9,5,1,2,2,3,4,9,7,8,9,9,2]
         for p in priorities: s.send(Message(priority=p))
-
-        # FIXME aconway 2012-02-22: there is a bug in priority ring
-        # queues that allows a low priority message to displace a high
-        # one. The following commented-out assert_browse is for the
-        # correct result, the uncommented one is for the actualy buggy
-        # result.  See https://issues.apache.org/jira/browse/QPID-3866
-        #
-        # expect = sorted(priorities,reverse=True)[0:5]
-        expect = [9,9,9,9,2]
+        expect = sorted(priorities,reverse=True)[0:5]
         primary.assert_browse("q", expect, transform=lambda m: m.priority)
         backup.assert_browse_backup("q", expect, transform=lambda m: m.priority)
 
@@ -963,7 +957,7 @@ class RecoveryTests(BrokerTest):
         """
         cluster = HaCluster(self, 3, args=["--ha-backup-timeout=0.5"]);
         cluster[0].wait_status("active") # Primary ready
-        for b in cluster[1:4]: b.wait_status("ready") # Backups ready
+        for b in cluster[1:3]: b.wait_status("ready") # Backups ready
         for i in [0,1]: cluster.kill(i, False)
         cluster[2].promote()    # New primary, backups will be 1 and 2
         cluster[2].wait_status("recovering")

Modified: qpid/branches/asyncstore/cpp/src/tests/sasl.mk
URL: http://svn.apache.org/viewvc/qpid/branches/asyncstore/cpp/src/tests/sasl.mk?rev=1377715&r1=1377714&r2=1377715&view=diff
==============================================================================
--- qpid/branches/asyncstore/cpp/src/tests/sasl.mk (original)
+++ qpid/branches/asyncstore/cpp/src/tests/sasl.mk Mon Aug 27 15:40:33 2012
@@ -20,13 +20,6 @@
 # Test that are only relevant if SASL is enabled.
 if HAVE_SASL
 
-if HAVE_LIBCPG
-check_PROGRAMS+=cluster_authentication_soak
-cluster_authentication_soak_INCLUDES=$(PUBLIC_INCLUDES)
-cluster_authentication_soak_SOURCES=cluster_authentication_soak.cpp  ForkedBroker.h ForkedBroker.cpp
-cluster_authentication_soak_LDADD=$(lib_client) $(lib_broker)
-endif HAVE_LIBCPG
-
 # Note: sasl_version is not a test -- it is a tool used by tests.
 check_PROGRAMS+=sasl_version
 sasl_version_SOURCES=sasl_version.cpp
@@ -39,30 +32,12 @@ TESTS += 	sasl_fed
 		sasl_fed_ex_route
 		sasl_no_dir
 
-if HAVE_LIBCPG
-
-TESTS +=	run_cluster_authentication_test 	\
-		sasl_fed_ex_route_cluster		\
-		sasl_fed_ex_link_cluster		\
-		sasl_fed_ex_queue_cluster		\
-		sasl_fed_ex_dynamic_cluster
-
-LONG_TESTS += run_cluster_authentication_soak
-
-endif HAVE_LIBCPG
-
-EXTRA_DIST += run_cluster_authentication_test \
-              sasl_fed                        \
+EXTRA_DIST += sasl_fed                        \
               sasl_fed_ex                     \
-              run_cluster_authentication_soak \
               sasl_fed_ex_dynamic             \
               sasl_fed_ex_link                \
               sasl_fed_ex_queue               \
               sasl_fed_ex_route               \
-              sasl_fed_ex_dynamic_cluster     \
-              sasl_fed_ex_link_cluster        \
-              sasl_fed_ex_queue_cluster       \
-              sasl_fed_ex_route_cluster       \
               sasl_no_dir
 
 

Modified: qpid/branches/asyncstore/cpp/src/tests/storePerftools/asyncPerf/MessageProducer.cpp
URL: http://svn.apache.org/viewvc/qpid/branches/asyncstore/cpp/src/tests/storePerftools/asyncPerf/MessageProducer.cpp?rev=1377715&r1=1377714&r2=1377715&view=diff
==============================================================================
--- qpid/branches/asyncstore/cpp/src/tests/storePerftools/asyncPerf/MessageProducer.cpp (original)
+++ qpid/branches/asyncstore/cpp/src/tests/storePerftools/asyncPerf/MessageProducer.cpp Mon Aug 27 15:40:33 2012
@@ -25,6 +25,7 @@
 
 #include "TestOptions.h"
 
+#include "qpid/asyncStore/PersistableMessageContext.h"
 #include "qpid/broker/SimpleMessage.h"
 #include "qpid/broker/SimpleQueue.h"
 #include "qpid/broker/SimpleTxnBuffer.h"
@@ -65,7 +66,10 @@ MessageProducer::runProducers() {
         tb = new qpid::broker::SimpleTxnBuffer(m_resultQueue);
     }
     for (uint32_t numMsgs=0; numMsgs<m_perfTestParams.m_numMsgs && !m_stopFlag; ++numMsgs) {
-        boost::intrusive_ptr<qpid::broker::SimpleMessage> msg(new qpid::broker::SimpleMessage(m_msgData, m_perfTestParams.m_msgSize, m_store));
+        boost::intrusive_ptr<qpid::asyncStore::PersistableMessageContext> msgCtxt(new qpid::asyncStore::PersistableMessageContext(m_store));
+        boost::intrusive_ptr<qpid::broker::AsyncCompletion> ingressCompl(new qpid::broker::AsyncCompletion);
+        msgCtxt->setIngressCompletion(ingressCompl);
+        boost::intrusive_ptr<qpid::broker::SimpleMessage> msg(new qpid::broker::SimpleMessage(m_msgData, m_perfTestParams.m_msgSize, msgCtxt));
         if (useTxns) {
             boost::shared_ptr<qpid::broker::SimpleTxnPublish> op(new qpid::broker::SimpleTxnPublish(msg));
             op->deliverTo(m_queue);

Modified: qpid/branches/asyncstore/cpp/src/tests/test_store.cpp
URL: http://svn.apache.org/viewvc/qpid/branches/asyncstore/cpp/src/tests/test_store.cpp?rev=1377715&r1=1377714&r2=1377715&view=diff
==============================================================================
--- qpid/branches/asyncstore/cpp/src/tests/test_store.cpp (original)
+++ qpid/branches/asyncstore/cpp/src/tests/test_store.cpp Mon Aug 27 15:40:33 2012
@@ -34,6 +34,7 @@
 
 #include "qpid/broker/NullMessageStore.h"
 #include "qpid/broker/Broker.h"
+#include "qpid/broker/amqp_0_10/MessageTransfer.h"
 #include "qpid/framing/AMQFrame.h"
 #include "qpid/log/Statement.h"
 #include "qpid/Plugin.h"
@@ -95,7 +96,7 @@ class TestStore : public NullMessageStor
                  const boost::intrusive_ptr<PersistableMessage>& pmsg,
                  const PersistableQueue& )
     {
-        Message* msg = dynamic_cast<Message*>(pmsg.get());
+        qpid::broker::amqp_0_10::MessageTransfer* msg = dynamic_cast<qpid::broker::amqp_0_10::MessageTransfer*>(pmsg.get());
         assert(msg);
 
         // Dump the message if there is a dump file.

Modified: qpid/branches/asyncstore/doc/book/src/cpp-broker/.gitignore
URL: http://svn.apache.org/viewvc/qpid/branches/asyncstore/doc/book/src/cpp-broker/.gitignore?rev=1377715&r1=1377714&r2=1377715&view=diff
==============================================================================
--- qpid/branches/asyncstore/doc/book/src/cpp-broker/.gitignore (original)
+++ qpid/branches/asyncstore/doc/book/src/cpp-broker/.gitignore Mon Aug 27 15:40:33 2012
@@ -1 +1,20 @@
+#
+# 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.
+#
+
 /output

Modified: qpid/branches/asyncstore/doc/book/src/java-broker/HA-Guide.xml
URL: http://svn.apache.org/viewvc/qpid/branches/asyncstore/doc/book/src/java-broker/HA-Guide.xml?rev=1377715&r1=1377714&r2=1377715&view=diff
==============================================================================
--- qpid/branches/asyncstore/doc/book/src/java-broker/HA-Guide.xml (original)
+++ qpid/branches/asyncstore/doc/book/src/java-broker/HA-Guide.xml Mon Aug 27 15:40:33 2012
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE urls [
 <!ENTITY oracleBdbProductOverviewUrl "http://www.oracle.com/technetwork/products/berkeleydb/overview/index-093405.html">
-<!ENTITY oracleBdbProductVersion "5.0.48">
+<!ENTITY oracleBdbProductVersion "5.0.58">
 <!ENTITY oracleBdbRepGuideUrl "http://oracle.com/cd/E17277_02/html/ReplicationGuide/">
 <!ENTITY oracleBdbJavaDocUrl "http://docs.oracle.com/cd/E17277_02/html/java/">
 <!ENTITY oracleJdkDocUrl "http://oracle.com/javase/6/docs/api/">
@@ -26,8 +26,9 @@
  under the License.
 
 -->
-<section>
+<section id="High-Availability">
   <title>High Availability</title>
+
   <section role="h3" id="HAGeneralIntroduction">
     <title>General Introduction</title>
     <para>The term High Availability (HA) usually refers to having a number of instances of a service such as a Message Broker
@@ -40,6 +41,7 @@
       some kind of standby state, awaiting to quickly step-in in the event the active node becomes unavailable.
     </para>
   </section>
+
   <section role="h3" id="HAOfferingsOfJavaBroker">
     <title>HA offerings of the Java Broker</title>
     <para>The Java Broker's HA offering became available at release <emphasis role="bold">0.18</emphasis>.  HA is provided by way of the HA
@@ -60,6 +62,7 @@
     <para>HA is not currently available for those using the the <emphasis role="bold">Derby Store</emphasis> or <emphasis role="bold">Memory
       Message Store</emphasis>.</para>
   </section>
+
   <section role="h3" id="HATwoNodeCluster">
     <title>Two Node Cluster</title>
     <section role="h4">
@@ -283,11 +286,13 @@
       </section>
     </section>
   </section>
+
   <section role="h3" id="HAMultiNodeCluster">
     <title>Multi Node Cluster</title>
     <para>Multi node clusters, that is clusters where the number of nodes is three or more, are not yet
          ready for use.</para>
   </section>
+
   <section role="h3" id="HAConfiguration">
     <title>Configuring a Virtual Host to be a node</title>
     <para>To configure a virtualhost as a cluster node, configure the virtualhost.xml in the following manner:</para>
@@ -385,6 +390,7 @@
     </store>]]></programlisting>
     </section>
   </section>
+
   <section role="h3" id="HADurabilityGuarantee">
     <title>Durability Guarantees</title>
     <para>The term <ulink url="http://en.wikipedia.org/wiki/ACID#Durability">durability</ulink> is used to mean that once a
@@ -480,6 +486,7 @@
       </para>
     </section>
   </section>
+
   <section id="HAClientFailover">
     <title>Client failover configuration</title>
     <para>The details about format of Qpid connection URLs can be found at section
@@ -495,6 +502,8 @@
 amqp://guest:guest@clientid/test?brokerlist='tcp://localhost:5672?connectdelay='2000'&retries='3';tcp://localhost:5671?connectdelay='2000'&retries='3';tcp://localhost:5673?connectdelay='2000'&retries='3''&failover='roundrobin?cyclecount='30''
         ]]></example>
   </section>
+
+
   <section role="h3" id="HAJMXAPI">
     <title>Qpid JMX API for HA</title>
     <para>Qpid exposes the BDB HA store information via its JMX interface and provides APIs to remove a Node from
@@ -569,6 +578,7 @@ amqp://guest:guest@clientid/test?brokerl
         </tr>
       </tbody>
     </table>
+
     <table border="1">
       <title>Mbean <classname>BDBHAMessageStore</classname> operations</title>
       <thead>
@@ -592,15 +602,15 @@ amqp://guest:guest@clientid/test?brokerl
           <td>updateAddress</td>
           <td>
             <itemizedlist>
-              <itemizedlist>
+              <listitem>
                 <para><emphasis>nodeName</emphasis>, name of node, string</para>
-              </itemizedlist>
-              <itemizedlist>
+              </listitem>
+              <listitem>
                 <para><emphasis>newHostName</emphasis>, new host name, string</para>
-              </itemizedlist>
-              <itemizedlist>
+              </listitem>
+              <listitem>
                 <para><emphasis>newPort</emphasis>, new port number, int</para>
-              </itemizedlist>
+              </listitem>
             </itemizedlist>
           </td>
           <td>void</td>
@@ -632,6 +642,7 @@ System.out.println("Node state:" + state
       <screen><![CDATA[Node state:MASTER]]></screen>
     </example>
   </section>
+
   <section id="BDB-HA-Monitoring-cluster">
     <title>Monitoring cluster</title>
     <para>In order to discover potential issues with HA Cluster early, all nodes in the Cluster should be monitored on regular basis
@@ -704,6 +715,7 @@ Current state of node: Node-5001 from gr
       </listitem>
     </itemizedlist>
   </section>
+
   <section id="HADiskSpace">
     <title>Disk space requirements</title>
     <para>Disk space is a critical resource for the HA Qpid broker.</para>
@@ -717,6 +729,7 @@ Current state of node: Node-5001 from gr
     Please, make sure to allocate enough space on your disk to avoid this from happening.
     </para>
   </section>
+
   <section id="BDB-HA-Network-Requirements">
     <title>Network Requirements</title>
     <para>The HA Cluster performance depends on the network bandwidth, its use by existing traffic, and quality of service.</para>
@@ -724,6 +737,7 @@ Current state of node: Node-5001 from gr
      which might include installation of dedicated network hardware on Broker hosts, assigning a higher priority to replication ports,
      installing a cluster in a separate network not impacted by any other traffic.</para>
   </section>
+
   <section id="BDB-HA-Security">
     <title>Security</title>
     <para>At the moment Berkeley replication API supports only TCP/IP protocol to transfer replication data between Master and Replicas.</para>
@@ -731,6 +745,7 @@ Current state of node: Node-5001 from gr
     <para>Also, anyone who can access to this network can introduce a new node and therefore receive a copy of the data.</para>
     <para>In order to reduce the security risks the entire HA cluster is recommended to run in a separate network protected from general access.</para>
   </section>
+
   <section id="BDB-HA-Backup">
     <title>Backups</title>
     <para>In order to protect the entire cluster from some cataclysms which might destroy all cluster nodes,
@@ -752,6 +767,7 @@ Current state of node: Node-5001 from gr
       the lifecycle of the cluster.</para>
     </note>
   </section>
+
   <section id="HAMigrationFromNonHA">
     <title>Migration of a non-HA store to HA</title>
     <para>Non HA stores starting from schema version 4 (0.14 Qpid release) can be automatically converted into HA store on broker startup if replication is first enabled with the <ulink url="&oracleBdbJavaDocUrl;com/sleepycat/je/rep/util/DbEnableReplication.html"><classname>DbEnableReplication</classname></ulink> utility from the BDB JE jar.</para>
@@ -782,6 +798,7 @@ java -jar je-&oracleBdbProductVersion;.j
       <para>Due to existing caveats in Berkeley JE with copying of data from Master into Replica it is recommended to restart the Master node after store schema upgrade is finished before starting the Replica nodes.</para>
     </note>
   </section>
+
   <section id="HADisasterRecovery">
     <title>Disaster Recovery</title>
     <para>This section describes the steps required to restore HA broker cluster from backup.</para>
@@ -987,4 +1004,5 @@ java -cp je-&oracleBdbProductVersion;.ja
     With this mode enabled, Qpid broker batches the concurrent transaction commits and syncs transaction data into Master disk in one go.
     As result, the HA performance only drops by 25-60% for durability <emphasis>NO_SYNC,NO_SYNC,ALL</emphasis> and by 10-90% for <emphasis>WRITE_NO_SYNC,WRITE_NO_SYNC,ALL</emphasis>.</para>
   </section>
+
 </section>

Modified: qpid/branches/asyncstore/doc/book/src/java-broker/images/HA-2N-Key.svg
URL: http://svn.apache.org/viewvc/qpid/branches/asyncstore/doc/book/src/java-broker/images/HA-2N-Key.svg?rev=1377715&r1=1377714&r2=1377715&view=diff
==============================================================================
--- qpid/branches/asyncstore/doc/book/src/java-broker/images/HA-2N-Key.svg (original)
+++ qpid/branches/asyncstore/doc/book/src/java-broker/images/HA-2N-Key.svg Mon Aug 27 15:40:33 2012
@@ -1,3 +1,23 @@
 <?xml version="1.0"?>
+<!--
+ 
+ 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.
+ 
+-->
 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
 <svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" viewBox="-7 -3 435 195" width="435pt" height="195pt"><metadata xmlns:dc="http://purl.org/dc/elements/1.1/"><dc:date>2012-05-31 06:19Z</dc:date><!-- Produced by OmniGraffle Professional 5.3.6 --></metadata><defs><filter id="Shadow" filterUnits="userSpaceOnUse"><feGaussianBlur in="SourceAlpha" result="blur" stdDeviation="3.488"/><feOffset in="blur" result="offset" dx="0" dy="4"/><feFlood flood-color="black" flood-opacity=".75" result="flood"/><feComposite in="flood" in2="offset" operator="in"/></filter><linearGradient x1="0" x2="1" id="Gradient" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="white"/><stop offset="1" stop-color="#2824aa"/></linearGradient><linearGradient id="Obj_Gradient" xl:href="#Gradient" gradientTransform="translate(52.803375 70.5) rotate(90) scale(24)"/><font-face font-family="Helvetica" font-size="12" units-per-em="1000" underline-position="-75.68359
 4" underline-thickness="49.316406" slope="0" x-height="522.94922" cap-height="717.28516" ascent="770.01953" descent="-229.98047" font-weight="500"><font-face-src><font-face-name name="Helvetica"/></font-face-src></font-face><linearGradient x1="0" x2="1" id="Gradient_2" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="white"/><stop offset="1" stop-color="#0caa25"/></linearGradient><linearGradient id="Obj_Gradient_2" xl:href="#Gradient_2" gradientTransform="translate(127.99037 28.999998) rotate(90) scale(25.5938)"/><linearGradient x1="0" x2="1" id="Gradient_3" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="white"/><stop offset="1" stop-color="#aa172d"/></linearGradient><linearGradient id="Obj_Gradient_3" xl:href="#Gradient_3" gradientTransform="translate(160.86441 28.999998) rotate(90) scale(25.5938)"/><linearGradient x1="0" x2="1" id="Gradient_4" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="white"/><stop offset="1" stop-color="#6923aa"/>
 </linearGradient><linearGradient id="Obj_Gradient_4" xl:href="#Gradient_4" gradientTransform="translate(52.803375 107.5) rotate(90) scale(24)"/><radialGradient cx="0" cy="0" r="1" id="Gradient_5" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="white"/><stop offset=".5" stop-color="#b5d0ea"/><stop offset="1" stop-color="#aaa"/></radialGradient><radialGradient id="Obj_Gradient_5" xl:href="#Gradient_5" gradientTransform="translate(56.678375 41.796898) scale(37.736065)"/><marker orient="auto" overflow="visible" markerUnits="strokeWidth" id="Arrow_Marker" viewBox="-1 -4 10 8" markerWidth="10" markerHeight="8" color="black"><g><path d="M 8 0 L 0 -3 L 0 3 Z" fill="none" stroke="currentColor" stroke-width="1"/></g></marker><marker orient="auto" overflow="visible" markerUnits="strokeWidth" id="FilledArrow_Marker" viewBox="-1 -3 6 6" markerWidth="6" markerHeight="6" color="black"><g><path d="M 3.7333333 0 L 0 -1.4 L 0 1.4 Z" fill="currentColor" stroke="currentColor" stroke
 -width="1"/></g></marker><linearGradient x1="0" x2="1" id="Gradient_6" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="white"/><stop offset="1" stop-color="#b5011d"/></linearGradient><linearGradient id="Obj_Gradient_6" xl:href="#Gradient_6" gradientTransform="translate(287.5 113.94637) rotate(90) scale(26.035202)"/><radialGradient cx="0" cy="0" r="1" id="Gradient_7" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="white"/><stop offset=".5" stop-color="#ea061f"/><stop offset="1" stop-color="#aaa"/></radialGradient><radialGradient id="Obj_Gradient_7" xl:href="#Gradient_7" gradientTransform="translate(280 41) scale(26.907248)"/><font-face font-family="Arial Unicode MS" font-size="36" panose-1="2 11 6 4 2 2 2 2 2 4" units-per-em="1000" underline-position="-100.097656" underline-thickness="49.804688" slope="0" x-height="529.78516" cap-height="728.02734" ascent="1068.84766" descent="-270.9961" font-weight="500"><font-face-src><font-face-name name="ArialUnico
 deMS"/></font-face-src></font-face></defs><g stroke="none" stroke-opacity="1" stroke-dasharray="none" fill="none" fill-opacity="1"><title>Canvas 7</title><g><title>Layer 1</title><g><use xl:href="#id240_Graphic" filter="url(#Shadow)"/><use xl:href="#id239_Graphic" filter="url(#Shadow)"/><use xl:href="#id238_Graphic" filter="url(#Shadow)"/><use xl:href="#id237_Graphic" filter="url(#Shadow)"/><use xl:href="#id236_Graphic" filter="url(#Shadow)"/><use xl:href="#id235_Graphic" filter="url(#Shadow)"/><use xl:href="#id229_Graphic" filter="url(#Shadow)"/><use xl:href="#id227_Graphic" filter="url(#Shadow)"/></g><g id="id240_Graphic"><rect x="13.999878" y="13" width="394.00012" height="155" fill="white"/><rect x="13.999878" y="13" width="394.00012" height="155" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/></g><g id="id239_Graphic"><rect x="28.177876" y="70.5" width="49.251003" height="24" fill="url(#Obj_Gradient)"/><rect x="28.177876" y="70.5" width=
 "49.251003" height="24" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(33.177876 75.5)" fill="black"><tspan font-family="Helvetica" font-size="12" font-weight="500" x="1.9536247" y="11" textLength="35.34375">Broker</tspan></text></g><g id="id238_Graphic"><path d="M 115.652176 41.796898 L 121.821274 28.999998 L 134.15947 28.999998 L 140.32857 41.796898 L 134.15947 54.593796 L 121.821274 54.593796 Z" fill="url(#Obj_Gradient_2)"/><path d="M 115.652176 41.796898 L 121.821274 28.999998 L 134.15947 28.999998 L 140.32857 41.796898 L 134.15947 54.593796 L 121.821274 54.593796 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/></g><g id="id237_Graphic"><path d="M 148.526215 41.796898 L 154.69531 28.999998 L 167.03351 28.999998 L 173.20261 41.796898 L 167.03351 54.593796 L 154.69531 54.593796 Z" fill="url(#Obj_Gradient_3)"/><path d="M 148.526215 41.796898 L 154.69531 28.999998 L 167.03351 28.99
 9998 L 173.20261 41.796898 L 167.03351 54.593796 L 154.69531 54.593796 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/></g><g id="id236_Graphic"><path d="M 32.853378 107.5 L 72.753372 107.5 C 77.472977 107.5 81.303375 112.876 81.303375 119.5 C 81.303375 126.124 77.472977 131.5 72.753372 131.5 L 32.853378 131.5 C 28.133776 131.5 24.303375 126.124 24.303375 119.5 C 24.303375 112.876 28.133776 107.5 32.853378 107.5" fill="url(#Obj_Gradient_4)"/><path d="M 32.853378 107.5 L 72.753372 107.5 C 77.472977 107.5 81.303375 112.876 81.303375 119.5 C 81.303375 126.124 77.472977 131.5 72.753372 131.5 L 32.853378 131.5 C 28.133776 131.5 24.303375 126.124 24.303375 119.5 C 24.303375 112.876 28.133776 107.5 32.853378 107.5" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(35.003376 112.5)" fill="black"><tspan font-family="Helvetica" font-size="12" font-weight="500" x="2.4601574" y="11" textLength="3
 0.679688">Client</tspan></text></g><g id="id235_Graphic"><path d="M 30.434645 43.17154 C 18.959625 41.796898 23.535576 30.224663 41.840797 32.199223 C 43.539116 28.35017 64.825623 28.974915 64.686462 32.199223 C 78.033752 28.075294 95.09079 36.298325 83.649857 40.422256 C 97.37842 42.421642 83.476616 53.194073 72.209625 51.394573 C 71.307922 54.39391 51.165936 55.443512 49.398033 51.394573 C 37.992596 55.718647 14.210434 49.070145 30.434645 43.17154 Z" fill="url(#Obj_Gradient_5)"/><path d="M 30.434645 43.17154 C 18.959625 41.796898 23.535576 30.224663 41.840797 32.199223 C 43.539116 28.35017 64.825623 28.974915 64.686462 32.199223 C 78.033752 28.075294 95.09079 36.298325 83.649857 40.422256 C 97.37842 42.421642 83.476616 53.194073 72.209625 51.394573 C 71.307922 54.39391 51.165936 55.443512 49.398033 51.394573 C 37.992596 55.718647 14.210434 49.070145 30.434645 43.17154 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="transl
 ate(36.828377 34.796898)" fill="black"><tspan font-family="Helvetica" font-size="12" font-weight="500" x=".84511757" y="11" textLength="38.009766">Cluster</tspan></text></g><text transform="translate(194.40121 29)" fill="black"><tspan font-family="Helvetica" font-size="12" font-weight="500" x="0" y="11" textLength="8.0039062">V</tspan><tspan font-family="Helvetica" font-size="12" font-weight="500" x="7.7929688" y="11" textLength="26.009766">irtual</tspan><tspan font-family="Helvetica" font-size="12" font-weight="500" x="0" y="25" textLength="22.68164">host</tspan></text><line x1="115.65217" y1="84" x2="162.7522" y2="84" marker-end="url(#Arrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><line x1="114.77717" y1="114.406006" x2="155.878815" y2="114.99225" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"/><text transform="translate(181.40121 70.5)" fill="black"><tspan
  font-family="Helvetica" font-size="12" font-weight="500" x="0" y="11" textLength="59.367188">Replication</tspan><tspan font-family="Helvetica" font-size="12" font-weight="500" x="0" y="25" textLength="36.673828">stream</tspan></text><text transform="translate(181.90121 93.906006)" fill="black"><tspan font-family="Helvetica" font-size="12" font-weight="500" x="0" y="25" textLength="30.679688">Client</tspan><tspan font-family="Helvetica" font-size="12" font-weight="500" x="0" y="39" textLength="58.04297">connection</tspan></text><g id="id229_Graphic"><path d="M 257.6145 123.341385 L 303.64609 123.13183 C 303.64609 123.13183 305.97821 110.84691 310.80124 114.69145 C 315.62408 118.53591 319 121.44636 319 121.44636 L 315.92612 122.44486 L 307.22827 122.069695 L 307.22821 132.69258 L 315.47678 133.06787 C 315.47678 133.06787 315.92618 136.46542 315.92618 136.78604 C 315.92618 137.10628 311.77792 139.65259 309.63474 139.972885 C 307.49097 140.29318 304.06018 131.63016 304.06018 13
 1.63039 C 304.06018 131.63039 257.61444 130.06921 257.48056 130.06921 C 257.34662 130.06921 256.13666 132.15001 256.00693 126.86558 C 255.87709 121.581276 257.6145 123.341385 257.6145 123.341385 Z" fill="url(#Obj_Gradient_6)"/><path d="M 257.6145 123.341385 L 303.64609 123.13183 C 303.64609 123.13183 305.97821 110.84691 310.80124 114.69145 C 315.62408 118.53591 319 121.44636 319 121.44636 L 315.92612 122.44486 L 307.22827 122.069695 L 307.22821 132.69258 L 315.47678 133.06787 C 315.47678 133.06787 315.92618 136.46542 315.92618 136.78604 C 315.92618 137.10628 311.77792 139.65259 309.63474 139.972885 C 307.49097 140.29318 304.06018 131.63016 304.06018 131.63039 C 304.06018 131.63039 257.61444 130.06921 257.48056 130.06921 C 257.34662 130.06921 256.13666 132.15001 256.00693 126.86558 C 255.87709 121.581276 257.6145 123.341385 257.6145 123.341385 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/></g><text transform="translate(334.09879 119.963974
 )" fill="black"><tspan font-family="Helvetica" font-size="12" font-weight="500" x="0" y="11" textLength="35.34961">Repair</tspan></text><g id="id227_Graphic"><path d="M 260 32.310394 L 275.19995 42.241386 L 263.13727 54.738464 L 267.99988 59 L 281.17648 45.481422 L 295.20001 54.655197 L 300 49.68975 L 284.79993 39.137974 L 297.59991 27.965553 L 290.39993 23 L 279.19989 35.413807 L 266.4 25.482777 Z" fill="url(#Obj_Gradient_7)"/><path d="M 260 32.310394 L 275.19995 42.241386 L 263.13727 54.738464 L 267.99988 59 L 281.17648 45.481422 L 295.20001 54.655197 L 300 49.68975 L 284.79993 39.137974 L 297.59991 27.965553 L 290.39993 23 L 279.19989 35.413807 L 266.4 25.482777 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/></g><text transform="translate(329.02448 34)" fill="black"><tspan font-family="Helvetica" font-size="12" font-weight="500" x="0" y="11" textLength="26.677734">Fault</tspan></text><text transform="translate(264 59.5)" fill="#262626">
 <tspan font-family="Arial Unicode MS" font-size="36" font-weight="500" fill="#262626" x="0" y="38" textLength="36">♛</tspan></text><text transform="translate(320.52448 72)" fill="black"><tspan font-family="Helvetica" font-size="12" font-weight="500" x="0" y="11" textLength="54.035156">Designate</tspan><tspan font-family="Helvetica" font-size="12" font-weight="500" x="0" y="25" textLength="41.332031">Primary</tspan></text></g></g></svg>



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