You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ch...@apache.org on 2016/01/18 22:21:51 UTC

[1/2] qpid-dispatch git commit: update work flow diagram

Repository: qpid-dispatch
Updated Branches:
  refs/heads/crolke-DISPATCH-188-1 e76044689 -> c284c20b8


update work flow diagram


Project: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/commit/6558a5d7
Tree: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/tree/6558a5d7
Diff: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/diff/6558a5d7

Branch: refs/heads/crolke-DISPATCH-188-1
Commit: 6558a5d7cc459ce73d2b61315c2fcfa302522851
Parents: e760446
Author: Chuck Rolke <cr...@redhat.com>
Authored: Wed Jan 13 14:22:23 2016 -0500
Committer: Chuck Rolke <cr...@redhat.com>
Committed: Wed Jan 13 14:22:23 2016 -0500

----------------------------------------------------------------------
 doc/notes/qdr-policy-diagrams-01.odg | Bin 32800 -> 37966 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/6558a5d7/doc/notes/qdr-policy-diagrams-01.odg
----------------------------------------------------------------------
diff --git a/doc/notes/qdr-policy-diagrams-01.odg b/doc/notes/qdr-policy-diagrams-01.odg
index 5521fb8..0e26174 100644
Binary files a/doc/notes/qdr-policy-diagrams-01.odg and b/doc/notes/qdr-policy-diagrams-01.odg differ


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


[2/2] qpid-dispatch git commit: Prepare for rework to get complete configuration from qdrouter.json.

Posted by ch...@apache.org.
Prepare for rework to get complete configuration from qdrouter.json.


Project: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/commit/c284c20b
Tree: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/tree/c284c20b
Diff: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/diff/c284c20b

Branch: refs/heads/crolke-DISPATCH-188-1
Commit: c284c20b828c5f491d7137a180029a819f7c7354
Parents: 6558a5d
Author: Chuck Rolke <cr...@redhat.com>
Authored: Mon Jan 18 16:18:48 2016 -0500
Committer: Chuck Rolke <cr...@redhat.com>
Committed: Mon Jan 18 16:18:48 2016 -0500

----------------------------------------------------------------------
 python/qpid_dispatch/management/qdrouter.json   | 169 +++++++++++--------
 .../qpid_dispatch_internal/management/config.py |  23 ++-
 .../management/policy_local.py                  | 136 ++++++++++++---
 3 files changed, 233 insertions(+), 95 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/c284c20b/python/qpid_dispatch/management/qdrouter.json
----------------------------------------------------------------------
diff --git a/python/qpid_dispatch/management/qdrouter.json b/python/qpid_dispatch/management/qdrouter.json
index 87c45ef..9d1aae0 100644
--- a/python/qpid_dispatch/management/qdrouter.json
+++ b/python/qpid_dispatch/management/qdrouter.json
@@ -1001,173 +1001,204 @@
         },
 
         "policy": {
-            "description": "Defines user connection and access policy",
+            "description": "Defines global connection limit",
             "extends": "configurationEntity",
             "singleton": true,
             "attributes": {
                 "maximumConnections": {
                     "type": "integer",
                     "default": 0,
-                    "description": "The maximum number of concurrent client connections allowed to this router. Zero implies no limit.",
+                    "description": "Global maximum number of concurrent client connections allowed. Zero implies no limit. This limit is always enforced even if no other policy settings have been defined.",
                     "required": false,
                     "create": true
                 },
-                "policyDb": {
-                    "type": "path",
-                    "description": "The path to the folder that holds local policy definition files.",
-		    "required": false,
-                    "create": true
-                },
                 "connectionsProcessed": {"type": "integer", "graph": true},
                 "connectionsDenied": {"type": "integer", "graph": true},
                 "connectionsCurrent": {"type": "integer", "graph": true}
             }
         },
 
-        "policy.appConnections": {
-            "description": "Defines per application connection limits, counts, and state.",
-            "extends": "operationalEntity",
+        "policy.accessRuleset": {
+            "description": "Per application definition of the locations from which users may connect and the groups to which users belong.",
+            "extends": "configurationEntity",
             "attributes": {
-                "appName": {
+                "name": {
                     "type": "string",
-                    "description": "Application to which these statistics apply",
-                    "create": true
+                    "description": "The application name.",
+                    "required": true
                 },
-
                 "maxConnections": {
                     "type": "integer",
-                    "description": "The maximum number of concurrent client connections allowed to this application. Zero implies no limit."
-                    },
+                    "default": 0,
+                    "description": "Maximum number of concurrent client connections allowed. Zero implies no limit.",
+                    "required": false,
+                    "create": true
+                },
                 "maxConnPerUser": {
                     "type": "integer",
-                    "description": "The maximum number of concurrent connections allowed to this application for a single authenticated user. Zero implies no limit."
-                    },
+                    "default": 0,
+                    "description": "Maximum number of concurrent client connections allowed for any single user. Zero implies no limit.",
+                    "required": false,
+                    "create": true
+                },
                 "maxConnPerHost": {
                     "type": "integer",
-                    "description": "The maximum number of concurrent connections allowed to this application from a remote host. Zero implies no limit."
+                    "default": 0,
+                    "description": "Maximum number of concurrent client connections allowed for any remote host. Zero implies no limit.",
+                    "required": false,
+                    "create": true
                 },
-
-                "connectionsApproved": {"type": "integer", "graph": true},
-                "connectionsDenied": {"type": "integer", "graph": true},
-                "connectionsActive": {"type": "integer", "graph": true},
-                "perUserState": {
+                "userGroups": {
                     "type": "map",
-                    "description": "Index is authenticated username; data is comma separated string naming the user's connections."
+                    "description": "A map where each key is a user group name and the corresponding value is a list of users in that group. Users who are assigned to one or more groups are deemed 'restricted'. Restricted users are subject to connection ingress policy and are assigned policy settings based on the assigned user groups. Unrestricted users may be allowed or denied. If unrestricted users are allowed to connect then they are assigned to user group default.",
+                    "required": false,
+                    "create": true
                 },
-                "perHostState": {
+                "connectionGroups": {
                     "type": "map",
-                    "description": "Index is remote host; data is comma separated string naming the host's connections."
+                    "description": "A map where each key is a connection group name and the corresponding value is a list of IP addresses in that group. IP addresses may be numeric IPv4 or IPv6 host address or comma separated host ranges.  The wildcard host address '*' represents any host address.",
+                    "required": false,
+                    "create": true
+                },
+                "connectionIngressPolicies": {
+                    "type": "map",
+                    "description": "A map where each key is a user group name and the corresponding value is a list of connection groups. Users who are members of the user group are allowed to connect only from a host in one of the named connection policy groups.",
+                    "required": false,
+                    "create": true
+                },
+                "connectionAllowDefault": {
+                    "type": "boolean",
+                    "description": "Unrestricted users, those who are not members of a defined user group, are allowed to connect to this application.",
+                    "default": false,
+                    "required": false,
+                    "create": true
                 }
             }
         },
-
-        "policy.appStatistics": {
-            "description": "Aggregated statistics for one application.",
+        "policy.accessStats": {
+            "description": "Per application connection and access statistics.",
             "extends": "operationalEntity",
             "attributes": {
-                "appName": {
+                "name": {
                     "type": "string",
-                    "description": "Application to which these statistics apply",
-                    "create": true
+                    "description": "The application name."
+                },
+                "connectionsApproved": {"type": "integer", "graph": true},
+                "connectionsDenied": {"type": "integer", "graph": true},
+                "connectionsCurrent": {"type": "integer", "graph": true},
+                "perUsrerState": {
+                    "type": "map",
+                    "description": "A map where the key is the authenticated user name and the value is a list of the user's connections."
                 },
+                "perHostState": {
+                    "type": "map",
+                    "description": "A map where the key is the host name and the value is a list of the host's connections."
+                }
 
-                "maxSendersDenials": {"type": "integer", "graph": true},
-                "maxReceiversDenials": {"type": "integer", "graph": true},
-                "dynamicSrcDenials": {"type": "integer", "graph": true},
-                "anonmousSenderDenials": {"type": "integer", "graph": true},
-                "sourceDenials": {"type": "integer", "graph": true},
-                "targetsDenials": {"type": "integer", "graph": true}
             }
-        },
 
-        "policy.appGroupSettings": {
-            "description": "Defines control values for a group of users in one application",
+        },
+        "policy.settings": {
+            "description": "For a given application and user group define the policy settings applied to the user's AMQP connection.",
             "extends": "configurationEntity",
             "attributes": {
-                "appName": {
+                "applicationName": {
                     "type": "string",
-                    "description": "Application to which these settings apply",
-                    "create": true
+                    "description": "The application to which these settings apply.",
+                    "required": true
                 },
-                "appGroupName": {
+                "groupName": {
                     "type": "string",
-                    "description": "Rule set name",
-                    "create": true
+                    "description": "The user group to which these settings apply.",
+                    "required": true
                 },
-
                 "maxFrameSize": {
                     "type": "integer",
-                    "default": 0,
-                    "description": "Largest frame that may be used on this connection. Value placed into forwarded AMQP Open.max-frame-size field. Zero implies inserting system default.",
+                    "description": "Largest frame that may be sent on this connection. Zero implies system default. (AMQP Open, max-frame-size)",
+                    "default": 65536,
                     "required": false,
                     "create": true
                 },
                 "maxMessageSize": {
                     "type": "integer",
+                    "description": "Largest message size supported by links created on this connection. Zero implies system default. (AMQP Attach, max-message-size)",
                     "default": 0,
-                    "description": "Largest message that may be used on this connection. Value placed into forwarded AMQP Attach.max-message-size field. Zero implies inserting system default.",
                     "required": false,
                     "create": true
                 },
                 "maxSessionWindow": {
                     "type": "integer",
-                    "default": 0,
-                    "description": "Largest incoming and outgoing window that may be used on this connection. Value placed into forwarded AMQP Begin.incoming-window and .outgoing-window fields. Zero implies inserting system default.",
+                    "description": "Largest incoming and outgoing window for sessions created on this connection. Zero implies system default. (AMQP Begin, incoming-window, outgoing-window)",
+                    "default": 2147483647,
                     "required": false,
                     "create": true
                 },
                 "maxSessions": {
                     "type": "integer",
-                    "default": 0,
-                    "description": "Maximum number of simultaneous sessions that may be used on this connection. Value placed into forwarded AMQP Open.channel-max field. Zero implies inserting system default.",
+                    "description": "Maximum number of sessions that may be created on this connection. Zero implies system default. (AMQP Open, channel-max)",
+                    "default": 10,
                     "required": false,
                     "create": true
                 },
                 "maxSenders": {
                     "type": "integer",
-                    "default": 0,
-                    "description": "Maximum number of simultaneous senders that may be used on this connection. Zero implies system default.",
+                    "description": "Maximum number of sending links that may be created on this connection. Zero implies system default.",
+                    "default": 10,
                     "required": false,
                     "create": true
                 },
                 "maxReceivers": {
                     "type": "integer",
-                    "default": 0,
-                    "description": "Maximum number of simultaneous receivers that may be used on this connection. Zero implies system default.",
+                    "description": "Maximum number of receiving links that may be created on this connection. Zero implies system default.",
                     "required": false,
                     "create": true
                 },
                 "allowDynamicSrc": {
                     "type": "boolean",
+                    "description": "This connection is allowed to use the dynamic link source feature.",
                     "default": false,
-                    "description": "A receiver link created on this connection is allowed to set the dynamic flag to true.",
                     "required": false,
                     "create": true
                 },
                 "allowAnonymousSender": {
                     "type": "boolean",
+                    "description": "This connection is allowed to use the Anonymous Sender feature.",
                     "default": false,
-                    "description": "A sender link created on this connection is allowed to have a blank target address.",
                     "required": false,
                     "create": true
                 },
                 "sources": {
-                    "type": "string",
-                    "default": 0,
-                    "description": "Comma separated list of allowed source addresses to be specified by receive links. A blank list denies all access. A list with a single wildcard address '*' allows all access. Simple beginsWith and endsWith may be specified by prefixing and postfixing a string with '*'. Username substitution is supported by using the $USER token in a string.",
+                    "type": "list",
+                    "description": "List of Source addresses allowed when creating receiving links.",
                     "required": false,
                     "create": true
                 },
                 "targets": {
-                    "type": "string",
-                    "default": 0,
-                    "description": "Comma separated list of allowed target addresses to be specified by sending links. A blank list denies all access. A list with a single wildcard address '*' allows all access. Simple beginsWith and endsWith may be specified by prefixing and postfixing a string with '*'. Username substitution is supported by using the $USER token in a string.",
+                    "type": "list",
+                    "description": "List of Target addresses allowed when creating sending links.",
                     "required": false,
                     "create": true
                 }
             }
         },
 
+        "policy.stats": {
+            "description": "Per application policy enforcement statistics.",
+            "extends": "operationalEntity",
+            "attributes": {
+                "name": {
+                    "type": "string",
+                    "description": "The application name."
+                },
+                "maxSendersDenied": {"type": "integer", "graph": true},
+                "maxReceiversDenied": {"type": "integer", "graph": true},
+                "dynamicSrcDenied": {"type": "integer", "graph": true},
+                "anonymousSenderDenied": {"type": "integer", "graph": true},
+                "linkSourceDenied": {"type": "integer", "graph": true},
+                "linkTargetDenied": {"type": "integer", "graph": true}
+            }
+        },
+
         "dummy": {
             "description": "Dummy entity for test purposes.",
             "extends": "entity",

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/c284c20b/python/qpid_dispatch_internal/management/config.py
----------------------------------------------------------------------
diff --git a/python/qpid_dispatch_internal/management/config.py b/python/qpid_dispatch_internal/management/config.py
index 65ab05b..979932e 100644
--- a/python/qpid_dispatch_internal/management/config.py
+++ b/python/qpid_dispatch_internal/management/config.py
@@ -30,13 +30,13 @@ from .qdrouter import QdSchema
 class Config(object):
     """Load config entities from qdrouterd.conf and validated against L{QdSchema}."""
 
-    def __init__(self, filename=None, schema=QdSchema()):
+    def __init__(self, filename=None, schema=QdSchema(), raw_json=False):
         self.schema = schema
         self.config_types = [et for et in schema.entity_types.itervalues()
                              if schema.is_configuration(et)]
         if filename:
             try:
-                self.load(filename)
+                self.load(filename, raw_json)
             except Exception, e:
                 raise Exception, "Cannot load configuration file %s: %s" % (filename, e), sys.exc_info()[2]
         else:
@@ -67,6 +67,17 @@ class Config(object):
             s[1] = dict((camelcase(k), v) for k, v in s[1].iteritems())
         return sections
 
+    @staticmethod
+    def _parserawjson(lines):
+        """Parse raw json config file format into a section list"""
+        def sub(line):
+            """Do substitutions to make line json-friendly"""
+            line = line.split('#')[0].strip() # Strip comments
+            return line
+        js_text = "%s"%("".join([sub(l) for l in lines]))
+        sections = json.loads(js_text)
+        return sections
+
 
     def _expand(self, content):
         """
@@ -90,16 +101,18 @@ class Config(object):
         return [_expand_section(s, annotations) for s in content
                 if self.schema.is_configuration(self.schema.entity_type(s[0], False))]
 
-    def load(self, source):
+    def load(self, source, raw_json=False):
         """
         Load a configuration file.
         @param source: A file name, open file object or iterable list of lines
+        @param raw_json: Source is pure json not needing conf-style substitutions
         """
         if isinstance(source, basestring):
+            raw_json |= source.endswith(".json")
             with open(source) as f:
-                self.load(f)
+                self.load(f, raw_json)
         else:
-            sections = self._parse(source)
+            sections = self._parserawjson(source) if raw_json else self._parse(source)
             # Add missing singleton sections
             for et in self.config_types:
                 if et.singleton and not [s for s in sections if s[0] == et.short_name]:

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/c284c20b/python/qpid_dispatch_internal/management/policy_local.py
----------------------------------------------------------------------
diff --git a/python/qpid_dispatch_internal/management/policy_local.py b/python/qpid_dispatch_internal/management/policy_local.py
index b9a91b4..8084fdc 100644
--- a/python/qpid_dispatch_internal/management/policy_local.py
+++ b/python/qpid_dispatch_internal/management/policy_local.py
@@ -31,25 +31,11 @@ import pdb #; pdb.set_trace()
 
 """
 Entity implementing the business logic of user connection/access policy.
-
-Policy is represented several ways:
-
-1. External       : json format file
-2. Internal       : dictionary
-
-Internal Policy:
-----------------
-
-    data['photoserver'] = 
-    {'groups': {'paidsubscribers': ['p1', 'p2'],
-               'users': ['u1', 'u2']}, 
-     'policyVersion': 1}
-
 """
 
 #
 #
-class PolicyKeys():
+class PolicyKeys(object):
     # Policy key words
     KW_POLICY_VERSION           = "policyVersion"
     KW_CONNECTION_ALLOW_DEFAULT = "connectionAllowDefault"
@@ -73,7 +59,7 @@ class PolicyKeys():
     SETTING_TARGETS                = "targets"
 #
 #
-class PolicyCompiler():
+class PolicyCompiler(object):
     """
     Validate incoming configuration for legal schema.
     - Warn about section options that go unused.
@@ -276,7 +262,7 @@ class PolicyCompiler():
                     return False
         return True
 
-class PolicyLocal():
+class PolicyLocal(object):
     """
     The policy database.
     """
@@ -291,6 +277,8 @@ class PolicyLocal():
         self.stats = {}
         self.folder = folder
         self.policy_compiler = PolicyCompiler()
+        self.name_lookup_cache = {}
+        self.blob_lookup_cache = {}
         if not folder == "":
             self.policy_io_read_files()
 
@@ -529,6 +517,7 @@ class PolicyLocal():
 
     def policy_lookup_settings(self, user, host, app, upolicy):
         """
+        HACK ALERT - delete this lookup. It is obsolete.
         Determine if a user on host accessing app through AMQP Open is allowed
         according to the policy access rules. 
         If allowed then return the policy settings.
@@ -577,7 +566,6 @@ class PolicyLocal():
             if not allowed:
                 return False
             # Return connection limits and aggregation of group settings
-            ugroups.append(user) # user groups also includes username directly
             self.policy_aggregate_limits     (upolicy, settings, PolicyKeys.KW_POLICY_VERSION)
             self.policy_aggregate_policy_int (upolicy, settings, ugroups, PolicyKeys.SETTING_MAX_FRAME_SIZE)
             self.policy_aggregate_policy_int (upolicy, settings, ugroups, PolicyKeys.SETTING_MAX_MESSAGE_SIZE)
@@ -600,6 +588,7 @@ class PolicyLocal():
 
     def policy_lookup(self, conn_id, user, host, app, upolicy):
         """
+        HACK ALERT - delete this lookup. It is obsolete.
         Determine if a user on host accessing app through AMQP Open is allowed:
         - verify to the policy access rules. 
         - track user/host connection limits
@@ -623,6 +612,102 @@ class PolicyLocal():
             return False
         return True
 
+    def lookup_users_policyname(self, user, host, app, policyname):
+        """
+        Determine if a user on host accessing app through AMQP Open is allowed
+        according to the policy access rules.
+        If allowed then return the policy settings name
+        @param[in] user connection authId
+        @param[in] host connection remote host numeric IP address as string
+        @param[in] app application user is accessing
+        @param[out] policyname name of the policy settings blob for this user
+        @return if allowed by policy
+        # Note: the upolicy output is a concatenated list of policy blob names.
+        """
+        try:
+            lookup_id = user + "|" + host + "|" + app
+            if lookup_id in self.name_lookup_cache:
+                policyname.append( self.name_lookup_cache[lookup_id] )
+                return True
+
+            settings = self.policydb[app]
+            # User allowed to connect from host?
+            allowed = False
+            restricted = False
+            uhs = HostStruct(host)
+            ugroups = []
+            if PolicyKeys.KW_GROUPS in settings:
+                for r in settings[PolicyKeys.KW_GROUPS]:
+                    if user in settings[PolicyKeys.KW_GROUPS][r]:
+                        restricted = True
+                        ugroups.append(r)
+            uorigins = []
+            if PolicyKeys.KW_CONNECTION_POLICY in settings:
+                for ur in ugroups:
+                    if ur in settings[PolicyKeys.KW_CONNECTION_POLICY]:
+                        uorigins.extend(settings[PolicyKeys.KW_CONNECTION_POLICY][ur])
+            if PolicyKeys.KW_CONNECTION_ORIGINS in settings:
+                for co in settings[PolicyKeys.KW_CONNECTION_ORIGINS]:
+                    if co in uorigins:
+                        for cohost in settings[PolicyKeys.KW_CONNECTION_ORIGINS][co]:
+                            if cohost.match_bin(uhs):
+                                allowed = True
+                                break
+                    if allowed:
+                        break
+            if not allowed and not restricted:
+                if PolicyKeys.KW_CONNECTION_ALLOW_DEFAULT in settings:
+                    allowed = settings[PolicyKeys.KW_CONNECTION_ALLOW_DEFAULT]
+            if not allowed:
+                return False
+            # Return connection limits and aggregation of group settings
+            ugroups.sort()
+            result = "|".join(ugroups)
+            self.name_lookup_cache[lookup_id] = result
+            policyname.append(result)
+            return True
+
+        except Exception, e:
+            #print str(e)
+            #pdb.set_trace()
+            return False
+
+    def lookup_named_settings(self, app, policyname, upolicy):
+        """
+        Given a settings name, return the aggregated policy blob.
+        @param[in] app application user is accessing
+        @param[in] policyname name of the policy settings blob
+        @param[out] upolicy dict holding policy values
+        @return if allowed by policy
+        # Note: the upolicy output is a non-nested dict with settings of interest
+        # TODO: figure out decent defaults for upolicy settings that are undefined
+        """
+        try:
+            cachekey = app + "|" + policyname
+            if cachekey in self.blob_lookup_cache:
+                upolicy.update( self.blob_lookup_cache[cachekey] )
+                return True
+            settings = self.policydb[app]
+            ugroups = policyname.split("|")
+            self.policy_aggregate_policy_int (upolicy, settings, ugroups, PolicyKeys.SETTING_MAX_FRAME_SIZE)
+            self.policy_aggregate_policy_int (upolicy, settings, ugroups, PolicyKeys.SETTING_MAX_MESSAGE_SIZE)
+            self.policy_aggregate_policy_int (upolicy, settings, ugroups, PolicyKeys.SETTING_MAX_SESSION_WINDOW)
+            self.policy_aggregate_policy_int (upolicy, settings, ugroups, PolicyKeys.SETTING_MAX_SESSIONS)
+            self.policy_aggregate_policy_int (upolicy, settings, ugroups, PolicyKeys.SETTING_MAX_SENDERS)
+            self.policy_aggregate_policy_int (upolicy, settings, ugroups, PolicyKeys.SETTING_MAX_RECEIVERS)
+            self.policy_aggregate_policy_bool(upolicy, settings, ugroups, PolicyKeys.SETTING_ALLOW_DYNAMIC_SRC)
+            self.policy_aggregate_policy_bool(upolicy, settings, ugroups, PolicyKeys.SETTING_ALLOW_ANONYMOUS_SENDER)
+            self.policy_aggregate_policy_list(upolicy, settings, ugroups, PolicyKeys.SETTING_SOURCES)
+            self.policy_aggregate_policy_list(upolicy, settings, ugroups, PolicyKeys.SETTING_TARGETS)
+            c_upolicy = {}
+            c_upolicy.update(upolicy)
+            self.blob_lookup_cache[cachekey] = c_upolicy
+            return True
+        except Exception, e:
+            #print str(e)
+            #pdb.set_trace()
+            return False
+
 
 #
 # HACK ALERT: Temporary
@@ -678,11 +763,20 @@ def main_except(argv):
     print "\nLookup ellen from 72.135.2.9. Expect true and maxFrameSize 666666. Result is %s" % res3
     print "Resulting policy is: %s" % upolicy
 
-    upolicy = {}
-    res4 = policy2.policy_lookup('72.135.2.9:33334', 'ellen', '72.135.2.9', 'photoserver', upolicy)
+    upolicy4 = {}
+    res4 = policy2.policy_lookup('72.135.2.9:33334', 'ellen', '72.135.2.9', 'photoserver', upolicy4)
     print "\nLookup policy2 ellen from 72.135.2.9. Expect false. Result is %s" % res4
 
-    if not (res1 and res2 and res3 and not res4):
+    policyname5 = []
+    res5 = policy.lookup_users_policyname('ellen', '72.135.2.9', 'photoserver', policyname5)
+    print "\nLookup user's policyname: %s" % policyname5
+
+    upolicy6 = {}
+    res6 = policy.lookup_named_settings('photoserver', policyname5[0], upolicy6)
+    res6a = upolicy6['maxFrameSize'] == 666666
+    print "\nNamed settings lookup result = %s, and value check = %s" % (res6, res6a)
+
+    if not (res1 and res2 and res3 and not res4 and res5 and res6 and res6a):
         print "Tests FAIL"
     else:
         print "Tests PASS"


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