You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ac...@apache.org on 2014/07/08 22:30:44 UTC

svn commit: r1608943 [2/3] - in /qpid/dispatch/trunk: ./ doc/man/ include/qpid/ include/qpid/dispatch/ python/qpid_dispatch_internal/ python/qpid_dispatch_internal/compat/ python/qpid_dispatch_internal/config/ python/qpid_dispatch_internal/management/ ...

Modified: qpid/dispatch/trunk/python/qpid_dispatch_internal/management/schema.py
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/python/qpid_dispatch_internal/management/schema.py?rev=1608943&r1=1608942&r2=1608943&view=diff
==============================================================================
--- qpid/dispatch/trunk/python/qpid_dispatch_internal/management/schema.py (original)
+++ qpid/dispatch/trunk/python/qpid_dispatch_internal/management/schema.py Tue Jul  8 20:30:42 2014
@@ -26,14 +26,9 @@ check for uniqueness of enties/attribute
 A Schema can be loaded/dumped to a json file.
 """
 
-import os, sys
+import os
 from entity import OrderedDict
 
-class ValidationError(Exception):
-    """Error raised if schema validation fails"""
-    pass
-
-
 def schema_file(name):
     """Return a file name relative to the directory from which this module was loaded."""
     return os.path.join(os.path.dirname(__file__), name)
@@ -91,20 +86,7 @@ class BooleanType(Type):
                 return self.VALUES[value.lower()]
             return bool(value)
         except:
-            raise ValidationError("Invalid Boolean value '%r'"%value)
-
-class EnumValue(str):
-    """A string that convets to an integer value via int()"""
-
-    def __new__(cls, name, value):
-        s = super(EnumValue, cls).__new__(cls, name)
-        setattr(s, 'value', value)
-        return s
-
-    def __int__(self): return self.value
-    def __eq__(self, x): return str(self) == x or int(self) == x
-    def __ne__(self, x): return not self == x
-    def __repr__(self): return "EnumValue('%s', %s)"%(str(self), int(self))
+            raise ValueError("Invalid Boolean value '%r'"%value)
 
 class EnumType(Type):
     """An enumerated type"""
@@ -117,22 +99,30 @@ class EnumType(Type):
         super(EnumType, self).__init__("enum%s"%([str(t) for t in tags]), int)
         self.tags = tags
 
-    def validate(self, value, **kwargs):
+    def validate(self, value, enum_as_int=False, **kwargs):
         """
         @param value: May be a string from the set of enum tag strings or anything
             that can convert to an int - in which case it must be in the enum range.
+        @keyword enum_as_int: If true the return value will be an int.
         @param kwargs: See L{Schema.validate}
-        @return: An EnumValue.
+        @return: If enum_as_int is True the int value of the enum, othewise the enum tag string.
         """
         if value in self.tags:
-            return EnumValue(value, self.tags.index(value))
+            if enum_as_int:
+                return self.tags.index(value)
+            else:
+                return value
         else:
             try:
                 i = int(value)
-                return EnumValue(self.tags[i], i)
+                if 0 <= i and i < len(self.tags):
+                    if enum_as_int:
+                        return i
+                    else:
+                        return self.tags[i]
             except (ValueError, IndexError):
                 pass
-        raise ValidationError("Invalid value for %s: '%r'"%(self.name, value))
+        raise ValueError("Invalid value for %s: '%r'"%(self.name, value))
 
     def dump(self):
         """
@@ -155,7 +145,7 @@ def get_type(rep):
         return EnumType(rep)
     if rep in BUILTIN_TYPES:
         return BUILTIN_TYPES[rep]
-    raise ValidationError("No such schema type: %s"%rep)
+    raise TypeError("No such schema type: %s"%rep)
 
 def _dump_dict(items):
     """
@@ -193,15 +183,15 @@ class AttributeType(object):
     @ivar name: Attribute name.
     @ivar atype: Attribute L{Type}
     @ivar required: True if the attribute is reqiured.
-    @ivar default: Default value for the attribute or None if no default. Can be a reference.
-    @ivar value: Fixed value for the attribute. Can be a reference.
+    @ivar default: Default value for the attribute or None if no default.
     @ivar unique: True if the attribute value is unique.
     @ivar description: Description of the attribute type.
     @ivar include: Include section or None
     """
 
-    def __init__(self, name, type=None, default=None, required=False, unique=False, value=None,
-                 include=None, description=""):
+    def __init__(self, name, type=None, default=None, required=False, unique=False, include=None,
+                 description=""
+    ): # pylint: disable=redefined-builtin
         """
         See L{AttributeType} instance variables.
         """
@@ -209,47 +199,33 @@ class AttributeType(object):
         self.atype = get_type(type)
         self.required = required
         self.default = default
-        self.value = value
         self.unique = unique
         self.description = description
+        if default is not None:
+            self.default = self.atype.validate(default)
         self.include = include
-        if self.value is not None and self.default is not None:
-            raise ValidationError("Attribute '%s' has default value and fixed value"%self.name)
 
-    def missing_value(self, check_required=True, add_default=True, **kwargs):
+    def validate(self, value, check_required=True, add_default=True, check_unique=None, **kwargs):
         """
-        Fill in missing default and fixed values but don't resolve references.
+        Validate value for this attribute definition.
         @keyword check_required: Raise an exception if required attributes are misssing.
         @keyword add_default:  Add a default value for missing attributes.
-        @param kwargs: See L{Schema.validate}
-        """
-        if self.value is not None: # Fixed value attribute
-            return self.value
-        if add_default and self.default is not None:
-            return self.default
-        if check_required and self.required:
-            raise ValidationError("Missing required attribute '%s'"%(self.name))
-
-
-    def validate(self, value, resolve=lambda x: x, check_unique=None, **kwargs):
-        """
-        Validate value for this attribute definition.
-        @param value: The value to validate.
-        @param resolve: function to resolve value references.
         @keyword check_unique: A dict to collect values to check for uniqueness.
             None means don't check for uniqueness.
         @param kwargs: See L{Schema.validate}
         @return: value converted to the correct python type. Rais exception if any check fails.
         """
-        value = resolve(value)
-        if self.unique and not _is_unique(check_unique, self.name, value):
-            raise ValidationError("Duplicate value '%s' for unique attribute '%s'"%(value, self.name))
-        if self.value and value != resolve(self.value):
-            raise ValidationError("Attribute '%s' has fixed value '%s' but given '%s'"%(self.name, resolve(self.value), value))
-        try:
+        if value is None and add_default:
+            value = self.default
+        if value is None:
+            if self.required and check_required:
+                raise ValueError("Missing value for attribute '%s'"%self.name)
+            else:
+                return None
+        else:
+            if self.unique and not _is_unique(check_unique, self.name, value):
+                raise ValueError("Multiple instances of unique attribute '%s'"%self.name)
             return self.atype.validate(value, **kwargs)
-        except (TypeError, ValueError), e:
-            raise ValidationError, str(e), sys.exc_info()[2]
 
     def dump(self):
         """
@@ -264,7 +240,7 @@ class AttributeType(object):
         ])
 
     def __str__(self):
-        return "%s(%s)"%(self.__class__.__name__, self.name)
+        return "AttributeType%s"%(self.__dict__)
 
 class AttributeTypeHolder(object):
     """Base class for IncludeType and EntityType - a named holder of attribute types"""
@@ -272,10 +248,10 @@ class AttributeTypeHolder(object):
     def __init__(self, name, schema, attributes=None, description=""):
         self.name, self.schema, self.description = name, schema, description
         self.attributes = OrderedDict()
+        self.attributes['type'] = AttributeType('type', type='String', default=name, required=True)
         if attributes:
             self.add_attributes(attributes)
 
-
     def add_attributes(self, attributes):
         """
         Add attributes.
@@ -283,7 +259,7 @@ class AttributeTypeHolder(object):
         """
         for k, v in attributes.iteritems():
             if k in self.attributes:
-                raise ValidationError("Duplicate attribute in '%s': '%s'"%(self.name, k))
+                raise TypeError("Duplicate attribute in '%s': '%s'"%(self.name, k))
             self.attributes[k] = AttributeType(k, **v)
 
     def dump(self):
@@ -294,16 +270,13 @@ class AttributeTypeHolder(object):
             ('description', self.description or None)
         ])
 
-
     def __str__(self):
-        return "%s(%s)"%(self.__class__.__name__, self.name)
-
+        print self.name
 
 class IncludeType(AttributeTypeHolder):
 
     def __init__(self, name, schema, attributes=None, description=""):
         super(IncludeType, self).__init__(name, schema, attributes, description)
-        attributes = attributes or {}
         for a in self.attributes.itervalues():
             a.include = self
 
@@ -327,13 +300,10 @@ class EntityType(AttributeTypeHolder):
         @param description: Human readable description.
         """
         super(EntityType, self).__init__(name, schema, attributes, description)
-        self.refs = {'entity-type': name}
         self.singleton = singleton
         self.include = include
         if include and self.schema.includes:
             for i in include:
-                if not i in schema.includes:
-                    raise ValidationError("Include '%s' not found in %s'"%(i, self))
                 for attr in schema.includes[i].attributes.itervalues():
                     self.attributes[attr.name] = attr
 
@@ -343,29 +313,6 @@ class EntityType(AttributeTypeHolder):
         if self.singleton: d['singleton'] = True
         return d
 
-    def resolve(self, value, attributes):
-        """
-        Resolve a $ or $$ reference.
-        $attr refers to another attribute.
-        $$name refers to a value in EntityType.refs
-        """
-        values = [value]
-        while True:
-            if isinstance(value, basestring) and value.startswith('$$'):
-                if value[2:] not in self.refs:
-                    raise ValidationError("Invalid entity type reference '%s'"%value)
-                value = self.refs[value[2:]]
-            elif isinstance(value, basestring) and value.startswith('$'):
-                if value[1:] not in self.attributes:
-                    raise ValidationError("Invalid attribute reference '%s'"%value)
-                value = attributes.get(value[1:])
-            else:
-                return value # Not a reference, don't need to resolve
-            if value == values[0]: # Circular reference
-                raise ValidationError("Unresolved circular reference '%s'"%values)
-            values.append(value)
-
-
     def validate(self, attributes, check_singleton=None, **kwargs):
         """
         Validate attributes.
@@ -374,36 +321,21 @@ class EntityType(AttributeTypeHolder):
         @param check_singleton: dict to enable singleton checking or None to disable.
         @param kwargs: See L{Schema.validate}
         """
-
-        def drop_none(): # Drop null items in attributes
-            for name in attributes.keys():
-                if attributes[name] is None:
-                    del attributes[name]
-
         if self.singleton and not _is_unique(check_singleton, self.name, True):
-            raise ValidationError("Multiple instances of singleton entity type '%s'"%self.name)
-
-        drop_none()
-
-        try:
-            # Add missing values
-            for attr in self.attributes.itervalues():
-                if attr.name not in attributes:
-                    value = attr.missing_value(**kwargs)
-                    if value is not None: attributes[attr.name] = value
-
-            # Validate attributes.
-            for name, value in attributes.iteritems():
-                if name not in self.attributes:
-                    raise ValidationError("%s has unknown attribute '%s'"%(self, name))
-                if name == 'type': value = self.schema.short_name(value) # Normalize type name
-                attributes[name] = self.attributes[name].validate(
-                    value, lambda v: self.resolve(v, attributes), **kwargs)
-        except ValidationError, e:
-            raise  ValidationError, "Entity '%s': %s"%(self.name, e), sys.exc_info()[2]
-
-        drop_none()
-
+            raise ValueError("Found multiple instances of singleton entity type '%s'"%self.name)
+        # Validate
+        for name, value in attributes.iteritems():
+            attributes[name] = self.attributes[name].validate(value, **kwargs)
+        # Set defaults, check for missing required values
+        for attr in self.attributes.itervalues():
+            if attr.name not in attributes:
+                value = attr.validate(None, **kwargs)
+                if not value is None:
+                    attributes[attr.name] = value
+        # Drop null items
+        for name in attributes.keys():
+            if attributes[name] is None:
+                del attributes[name]
         return attributes
 
 
@@ -453,29 +385,25 @@ class Schema(object):
                 'includes': OrderedDict((k, v.dump()) for k, v in self.includes.iteritems()),
                 'entity_types': OrderedDict((k, v.dump()) for k, v in self.entity_types.iteritems())}
 
-    def validate(self, entities, check_required=True, add_default=True, check_unique=True, check_singleton=True):
+    def validate(self, entities, enum_as_int=False, check_required=True, add_default=True, check_unique=True, check_singleton=True):
         """
         Validate entities, verify singleton entities and unique attributes are unique.
 
         @param entities: List of L{Entity}
+        @keyword enum_as_int: Represent enums as int rather than string.
         @keyword check_required: Raise exception if required attributes are missing.
         @keyword add_default: Add defaults for missing attributes.
         @keyword check_unique: Raise exception if unique attributes are duplicated.
-        @keyword check_singleton: Raise exception if singleton entities are duplicated or missing
+        @keyword check_singleton: Raise exception if singleton entities are duplicated.
         """
         if check_singleton: check_singleton = {}
         if check_unique: check_unique = {}
-
-        # Validate all entities.
         for e in entities:
-            e.type = self.short_name(e.type)
-            if not e.type in self.entity_types:
-                raise ValidationError("No such entity type: '%s'" % e.type)
             et = self.entity_types[e.type]
             et.validate(e,
+                        enum_as_int=enum_as_int,
                         check_required=check_required,
                         add_default=add_default,
                         check_unique=check_unique,
                         check_singleton=check_singleton)
-
         return entities

Copied: qpid/dispatch/trunk/python/qpid_dispatch_internal/ordereddict.py (from r1608937, qpid/dispatch/trunk/python/qpid_dispatch_internal/compat/ordereddict.py)
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/python/qpid_dispatch_internal/ordereddict.py?p2=qpid/dispatch/trunk/python/qpid_dispatch_internal/ordereddict.py&p1=qpid/dispatch/trunk/python/qpid_dispatch_internal/compat/ordereddict.py&r1=1608937&r2=1608943&rev=1608943&view=diff
==============================================================================
    (empty)

Modified: qpid/dispatch/trunk/python/qpid_dispatch_internal/router/__init__.py
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/python/qpid_dispatch_internal/router/__init__.py?rev=1608943&r1=1608942&r2=1608943&view=diff
==============================================================================
--- qpid/dispatch/trunk/python/qpid_dispatch_internal/router/__init__.py (original)
+++ qpid/dispatch/trunk/python/qpid_dispatch_internal/router/__init__.py Tue Jul  8 20:30:42 2014
@@ -17,6 +17,4 @@
 # under the License.
 #
 
-from .engine import RouterEngine
-
-__all__ = ["RouterEngine"]
+from .engine import *

Modified: qpid/dispatch/trunk/python/qpid_dispatch_internal/router/data.py
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/python/qpid_dispatch_internal/router/data.py?rev=1608943&r1=1608942&r2=1608943&view=diff
==============================================================================
--- qpid/dispatch/trunk/python/qpid_dispatch_internal/router/data.py (original)
+++ qpid/dispatch/trunk/python/qpid_dispatch_internal/router/data.py Tue Jul  8 20:30:42 2014
@@ -17,6 +17,13 @@
 # under the License.
 #
 
+
+try:
+    from dispatch import *
+except ImportError:
+    from ..stubs import *
+
+
 def getMandatory(data, key, cls=None):
     """
     Get the value mapped to the requested key.    If it's not present, raise an exception.
@@ -271,3 +278,4 @@ class MessageMAR(object):
         return {'id'       : self.id,
                 'area'     : self.area,
                 'have_seq' : self.have_seq}
+

Modified: qpid/dispatch/trunk/python/qpid_dispatch_internal/router/engine.py
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/python/qpid_dispatch_internal/router/engine.py?rev=1608943&r1=1608942&r2=1608943&view=diff
==============================================================================
--- qpid/dispatch/trunk/python/qpid_dispatch_internal/router/engine.py (original)
+++ qpid/dispatch/trunk/python/qpid_dispatch_internal/router/engine.py Tue Jul  8 20:30:42 2014
@@ -18,16 +18,16 @@
 #
 
 from time import time
+from uuid import uuid4
 
 from configuration import Configuration
-from data import MessageHELLO, MessageRA, MessageLSU, MessageMAU, MessageMAR, MessageLSR
+from data import *
 from neighbor import NeighborEngine
 from link import LinkStateEngine
 from path import PathEngine
 from mobile import MobileAddressEngine
 from routing import RoutingTableEngine
 from node import NodeTracker
-from message import Message
 
 import sys
 import traceback
@@ -36,7 +36,11 @@ import traceback
 ## Import the Dispatch adapters from the environment.  If they are not found
 ## (i.e. we are in a test bench, etc.), load the stub versions.
 ##
-from dispatch import IoAdapter, LogAdapter, LOG_TRACE, LOG_DEBUG, LOG_INFO, LOG_ERROR
+try:
+    from dispatch import *
+except ImportError:
+    from ..stubs import *
+
 
 class RouterEngine:
     """
@@ -52,8 +56,7 @@ class RouterEngine:
         self.domain         = "domain"
         self.router_adapter = router_adapter
         self.log_adapter    = LogAdapter("ROUTER")
-        self.io_adapter     = [IoAdapter(self.receive, "qdrouter"),
-                               IoAdapter(self.receive, "qdhello")]
+        self.io_adapter     = IoAdapter(self, ("qdrouter", "qdhello"))
         self.max_routers    = max_routers
         self.id             = router_id
         self.area           = area
@@ -182,15 +185,16 @@ class RouterEngine:
             traceback.print_tb(exc_traceback)
 
 
-    def receive(self, message, link_id):
+    def receive(self, message_properties, body, link_id):
         """
         This is the IoAdapter message-receive handler
         """
         try:
-            self.handleControlMessage(message.properties['opcode'], message.body, link_id)
+            #self.log(LOG_DEBUG, "Raw Receive: mp=%r body=%r link_id=%r" % (message_properties, body, link_id))
+            self.handleControlMessage(message_properties['opcode'], body, link_id)
         except Exception, e:
             self.log(LOG_ERROR, "Exception in raw message processing: properties=%r body=%r exception=%r" %
-                     (message.properties, message.body, e))
+                     (message_properties, body, e))
             exc_type, exc_value, exc_traceback = sys.exc_info()
             traceback.print_tb(exc_traceback)
 
@@ -230,7 +234,7 @@ class RouterEngine:
         Send a control message to another router.
         """
         app_props = {'opcode' : msg.get_opcode() }
-        self.io_adapter[0].send(Message(address=dest, properties=app_props, body=msg.to_dict()))
+        self.io_adapter.send(dest, app_props, msg.to_dict())
         self.log(LOG_TRACE, "SENT: %r dest=%s" % (msg, dest))
 
 
@@ -298,3 +302,4 @@ class RouterEngine:
     def del_remote_router(self, router_bit):
         self.log(LOG_DEBUG, "Event: del_remote_router: router_bit=%d" % router_bit)
         self.router_adapter.del_remote_router(router_bit)
+

Modified: qpid/dispatch/trunk/python/qpid_dispatch_internal/router/link.py
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/python/qpid_dispatch_internal/router/link.py?rev=1608943&r1=1608942&r2=1608943&view=diff
==============================================================================
--- qpid/dispatch/trunk/python/qpid_dispatch_internal/router/link.py (original)
+++ qpid/dispatch/trunk/python/qpid_dispatch_internal/router/link.py Tue Jul  8 20:30:42 2014
@@ -18,7 +18,12 @@
 #
 
 from data import MessageRA, MessageLSU, MessageLSR
-from dispatch import LOG_INFO
+from time import time
+
+try:
+    from dispatch import *
+except ImportError:
+    from ..stubs import *
 
 class LinkStateEngine(object):
     """

Modified: qpid/dispatch/trunk/python/qpid_dispatch_internal/router/mobile.py
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/python/qpid_dispatch_internal/router/mobile.py?rev=1608943&r1=1608942&r2=1608943&view=diff
==============================================================================
--- qpid/dispatch/trunk/python/qpid_dispatch_internal/router/mobile.py (original)
+++ qpid/dispatch/trunk/python/qpid_dispatch_internal/router/mobile.py Tue Jul  8 20:30:42 2014
@@ -17,8 +17,12 @@
 # under the License.
 #
 
-from data import MessageMAR, MessageMAU
-from dispatch import LOG_DEBUG
+from data import MessageRA, MessageMAR, MessageMAU
+
+try:
+    from dispatch import *
+except ImportError:
+    from ..stubs import *
 
 class MobileAddressEngine(object):
     """
@@ -183,3 +187,4 @@ class MobileAddressEngine(object):
         if deleted != None:
             for d in deleted:
                 self.container.router_adapter.unmap_destination(d[0], d[1:], bit)
+

Modified: qpid/dispatch/trunk/python/qpid_dispatch_internal/router/neighbor.py
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/python/qpid_dispatch_internal/router/neighbor.py?rev=1608943&r1=1608942&r2=1608943&view=diff
==============================================================================
--- qpid/dispatch/trunk/python/qpid_dispatch_internal/router/neighbor.py (original)
+++ qpid/dispatch/trunk/python/qpid_dispatch_internal/router/neighbor.py Tue Jul  8 20:30:42 2014
@@ -18,7 +18,13 @@
 #
 
 from data import LinkState, MessageHELLO
-from dispatch import LOG_INFO
+from time import time
+
+try:
+    from dispatch import *
+except ImportError:
+    from ..stubs import *
+
 
 class NeighborEngine(object):
     """
@@ -80,3 +86,4 @@ class NeighborEngine(object):
                 to_delete.append(key)
         for key in to_delete:
             self._delete_neighbor(key)
+

Modified: qpid/dispatch/trunk/python/qpid_dispatch_internal/router/node.py
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/python/qpid_dispatch_internal/router/node.py?rev=1608943&r1=1608942&r2=1608943&view=diff
==============================================================================
--- qpid/dispatch/trunk/python/qpid_dispatch_internal/router/node.py (original)
+++ qpid/dispatch/trunk/python/qpid_dispatch_internal/router/node.py Tue Jul  8 20:30:42 2014
@@ -17,6 +17,12 @@
 # under the License.
 #
 
+try:
+    from dispatch import *
+except ImportError:
+    from ..stubs import *
+
+
 class NodeTracker(object):
     """
     This module is responsible for tracking the set of router nodes that are known to this
@@ -177,3 +183,4 @@ class RemoteNode(object):
         self.remote   = not neighbor
         self.link_id  = link_id
         self.addrs    = {}  # Address => Count at Node (1 only for the present)
+

Modified: qpid/dispatch/trunk/python/qpid_dispatch_internal/router/path.py
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/python/qpid_dispatch_internal/router/path.py?rev=1608943&r1=1608942&r2=1608943&view=diff
==============================================================================
--- qpid/dispatch/trunk/python/qpid_dispatch_internal/router/path.py (original)
+++ qpid/dispatch/trunk/python/qpid_dispatch_internal/router/path.py Tue Jul  8 20:30:42 2014
@@ -17,6 +17,10 @@
 # under the License.
 #
 
+try:
+    from dispatch import *
+except ImportError:
+    from ..stubs import *
 
 class PathEngine(object):
     """
@@ -228,3 +232,4 @@ class NodeSet(object):
             index += 1
 
         self.nodes.insert(index, (_id, new_cost))
+

Modified: qpid/dispatch/trunk/python/qpid_dispatch_internal/router/routing.py
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/python/qpid_dispatch_internal/router/routing.py?rev=1608943&r1=1608942&r2=1608943&view=diff
==============================================================================
--- qpid/dispatch/trunk/python/qpid_dispatch_internal/router/routing.py (original)
+++ qpid/dispatch/trunk/python/qpid_dispatch_internal/router/routing.py Tue Jul  8 20:30:42 2014
@@ -17,6 +17,11 @@
 # under the License.
 #
 
+try:
+    from dispatch import *
+except ImportError:
+    from ..stubs import *
+
 class RoutingTableEngine(object):
     """
     This module is responsible for converting the set of next hops to remote routers to a routing
@@ -57,3 +62,4 @@ class RoutingTableEngine(object):
 
     def get_next_hops(self):
         return self.next_hops
+

Copied: qpid/dispatch/trunk/python/qpid_dispatch_internal/stubs/__init__.py (from r1608937, qpid/dispatch/trunk/python/qpid_dispatch_internal/router/__init__.py)
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/python/qpid_dispatch_internal/stubs/__init__.py?p2=qpid/dispatch/trunk/python/qpid_dispatch_internal/stubs/__init__.py&p1=qpid/dispatch/trunk/python/qpid_dispatch_internal/router/__init__.py&r1=1608937&r2=1608943&rev=1608943&view=diff
==============================================================================
--- qpid/dispatch/trunk/python/qpid_dispatch_internal/router/__init__.py (original)
+++ qpid/dispatch/trunk/python/qpid_dispatch_internal/stubs/__init__.py Tue Jul  8 20:30:42 2014
@@ -17,6 +17,6 @@
 # under the License.
 #
 
-from .engine import RouterEngine
+from .logadapter import *
+from .ioadapter  import *
 
-__all__ = ["RouterEngine"]

Copied: qpid/dispatch/trunk/python/qpid_dispatch_internal/stubs/ioadapter.py (from r1608937, qpid/dispatch/trunk/python/qpid_dispatch_internal/compat/__init__.py)
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/python/qpid_dispatch_internal/stubs/ioadapter.py?p2=qpid/dispatch/trunk/python/qpid_dispatch_internal/stubs/ioadapter.py&p1=qpid/dispatch/trunk/python/qpid_dispatch_internal/compat/__init__.py&r1=1608937&r2=1608943&rev=1608943&view=diff
==============================================================================
--- qpid/dispatch/trunk/python/qpid_dispatch_internal/compat/__init__.py (original)
+++ qpid/dispatch/trunk/python/qpid_dispatch_internal/stubs/ioadapter.py Tue Jul  8 20:30:42 2014
@@ -14,19 +14,14 @@
 # "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
+# under the License.
 #
 
-"""Compatibility hacks for older versions of python"""
+class IoAdapter:
+  def __init__(self, handler, address):
+    self.handler = handler
+    self.address = address
 
-import sys
+  def send(self, address, app_properties, body):
+    print "IO: send(addr=%s props=%r body=%r" % (address, app_properties, body)
 
-__all__ = ["OrderedDict"]
-
-try: from collections import OrderedDict
-except: from ordereddict import OrderedDict
-
-if sys.version_info >= (2,7):
-    json_load_kwargs = {'object_pairs_hook':OrderedDict}
-else:
-    json_load_kwargs = {}

Copied: qpid/dispatch/trunk/python/qpid_dispatch_internal/stubs/logadapter.py (from r1608937, qpid/dispatch/trunk/tests/mock/dispatch.py)
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/python/qpid_dispatch_internal/stubs/logadapter.py?p2=qpid/dispatch/trunk/python/qpid_dispatch_internal/stubs/logadapter.py&p1=qpid/dispatch/trunk/tests/mock/dispatch.py&r1=1608937&r2=1608943&rev=1608943&view=diff
==============================================================================
--- qpid/dispatch/trunk/tests/mock/dispatch.py (original)
+++ qpid/dispatch/trunk/python/qpid_dispatch_internal/stubs/logadapter.py Tue Jul  8 20:30:42 2014
@@ -1,3 +1,4 @@
+#
 # 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
@@ -16,10 +17,6 @@
 # under the License.
 #
 
-"""
-Mock implementation of the dispatch C extension module for use in unit tests.
-"""
-
 LOG_TRACE    = 1
 LOG_DEBUG    = 2
 LOG_INFO     = 4
@@ -34,12 +31,3 @@ class LogAdapter:
 
   def log(self, level, text):
     print "LOG: mod=%s level=%d text=%s" % (self.mod_name, level, text)
-
-class IoAdapter:
-  def __init__(self, handler, address, global_address=False):
-    self.handler = handler
-    self.address = address
-    self.global_address = global_address
-
-  def send(self, address, properties, application_properties, body, correlation_id=None):
-    print "IO: send(addr=%s properties=%r application_properties=%r body=%r" % (address, properties, application_properties, body)

Modified: qpid/dispatch/trunk/python/qpid_dispatch_internal/tools/__init__.py
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/python/qpid_dispatch_internal/tools/__init__.py?rev=1608943&r1=1608942&r2=1608943&view=diff
==============================================================================
--- qpid/dispatch/trunk/python/qpid_dispatch_internal/tools/__init__.py (original)
+++ qpid/dispatch/trunk/python/qpid_dispatch_internal/tools/__init__.py Tue Jul  8 20:30:42 2014
@@ -6,9 +6,9 @@
 # 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
@@ -17,6 +17,5 @@
 # under the License.
 #
 
-from .display import Display, Header, Sorter, YN, Commas, TimeLong, TimeShort, Sortable
+from .display import *
 
-__all__ = ["Display", "Header", "Sorter", "YN", "Commas", "TimeLong", "TimeShort", "Sortable"]

Modified: qpid/dispatch/trunk/router/src/config.h.in
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/router/src/config.h.in?rev=1608943&r1=1608942&r2=1608943&view=diff
==============================================================================
--- qpid/dispatch/trunk/router/src/config.h.in (original)
+++ qpid/dispatch/trunk/router/src/config.h.in Tue Jul  8 20:30:42 2014
@@ -6,9 +6,9 @@
  * 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
@@ -19,6 +19,3 @@
 
 #cmakedefine DEFAULT_CONFIG_PATH          "${DEFAULT_CONFIG_PATH}"
 #cmakedefine QPID_DISPATCH_HOME_INSTALLED "${QPID_DISPATCH_HOME_INSTALLED}"
-
-// Use #define, not #cmakedefine because SO_VERSION_MAJOR may be 0 which #cmakedefine considers unset.
-#define QPID_DISPATCH_LIB "libqpid-dispatch.so.${SO_VERSION_MAJOR}"

Modified: qpid/dispatch/trunk/router/src/main.c
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/router/src/main.c?rev=1608943&r1=1608942&r2=1608943&view=diff
==============================================================================
--- qpid/dispatch/trunk/router/src/main.c (original)
+++ qpid/dispatch/trunk/router/src/main.c Tue Jul  8 20:30:42 2014
@@ -29,6 +29,20 @@ static int            exit_with_sigint =
 static qd_dispatch_t *dispatch = 0;
 static qd_log_source_t *log_source = 0;
 
+static const char *app_config =
+    "from qpid_dispatch_internal.config.schema import config_schema\n"
+    "config_schema['fixed-address'] = (False, {\n"
+    "   'prefix' : (str, 0, 'M', None, None),\n"
+    "   'phase'  : (int, 1, '', 0, None),\n"
+    "   'fanout' : (str, None, '', 'multiple', ['multiple', 'single']),\n"
+    "   'bias'   : (str, None, '', 'closest',  ['closest', 'spread'])})\n"
+    "config_schema['waypoint'] = (False, {\n"
+    "   'name'      : (str, 0,    'M', None, None),\n"
+    "   'in-phase'  : (int, None, '',  -1, None),\n"
+    "   'out-phase' : (int, None, '',  -1, None),\n"
+    "   'connector' : (str, None, 'M', None, None)})\n";
+
+
 /**
  * The thread_start_handler is invoked once for each server thread at thread startup.
  */
@@ -88,7 +102,6 @@ int main(int argc, char **argv)
 #define DEFAULT_DISPATCH_PYTHON_DIR QPID_DISPATCH_HOME_INSTALLED "/python"
     const char *config_path   = DEFAULT_CONFIG_PATH;
     const char *python_pkgdir = DEFAULT_DISPATCH_PYTHON_DIR;
-    const char *qpid_dispatch_lib = QPID_DISPATCH_LIB;
 
     static struct option long_options[] = {
     {"config",  required_argument, 0, 'c'},
@@ -127,13 +140,23 @@ int main(int argc, char **argv)
 
 
     qd_error_clear();
-    dispatch = qd_dispatch(python_pkgdir, qpid_dispatch_lib);
-    check();
+    dispatch = qd_dispatch(python_pkgdir);
+    qd_dispatch_extend_config_schema(dispatch, app_config);
     log_source = qd_log_source("MAIN"); /* Logging is initialized by qd_dispatch. */
+    check();
     qd_dispatch_load_config(dispatch, config_path);
     check();
+    qd_log_configure(dispatch);
+    check();
+    qd_dispatch_configure_container(dispatch);
+    check();
+    qd_dispatch_configure_router(dispatch);
+    check();
+    qd_dispatch_prepare(dispatch);
+    check();
+    qd_dispatch_post_configure_connections(dispatch);
+    check();
 
-    (void)server_signal_handler; (void)thread_start_handler;(void)signal_handler;
     qd_server_set_signal_handler(dispatch, server_signal_handler, 0);
     qd_server_set_start_handler(dispatch, thread_start_handler, 0);
 

Added: qpid/dispatch/trunk/src/config.c
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/config.c?rev=1608943&view=auto
==============================================================================
--- qpid/dispatch/trunk/src/config.c (added)
+++ qpid/dispatch/trunk/src/config.c Tue Jul  8 20:30:42 2014
@@ -0,0 +1,278 @@
+/*
+ * 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.
+ */
+
+#include <qpid/dispatch/python_embedded.h>
+#include "dispatch_private.h"
+#include <qpid/dispatch/alloc.h>
+#include <qpid/dispatch/log.h>
+
+#define PYTHON_MODULE "qpid_dispatch_internal.config"
+
+static qd_log_source_t *log_source = 0;
+
+struct qd_config_t {
+    PyObject *pModule;
+    PyObject *pClass;
+    PyObject *pObject;
+};
+
+ALLOC_DECLARE(qd_config_t);
+ALLOC_DEFINE(qd_config_t);
+
+void qd_config_initialize(void)
+{
+    log_source = qd_log_source("CONFIG");
+    qd_python_start();
+}
+
+
+void qd_config_finalize(void)
+{
+    qd_python_stop();
+}
+
+
+qd_config_t *qd_config(void)
+{
+    qd_config_t *config = new_qd_config_t();
+
+    //
+    // Load the Python configuration module and get a reference to the config class.
+    //
+    PyObject *pName = PyString_FromString(PYTHON_MODULE);
+    config->pModule = PyImport_Import(pName);
+    Py_DECREF(pName);
+
+    if (!config->pModule) {
+        qd_error_py();
+        free_qd_config_t(config);
+        qd_log(log_source, QD_LOG_ERROR, "Unable to load configuration module: %s", PYTHON_MODULE);
+        return 0;
+    }
+
+    config->pClass = PyObject_GetAttrString(config->pModule, "DispatchConfig");
+    if (!config->pClass || !PyClass_Check(config->pClass)) {
+        PyErr_Print();
+        Py_DECREF(config->pModule);
+        free_qd_config_t(config);
+        qd_log(log_source, QD_LOG_ERROR, "Problem with configuration module: Missing DispatchConfig class");
+        return 0;
+    }
+
+    //
+    // Instantiate the DispatchConfig class
+    //
+    PyObject *pArgs = PyTuple_New(0);
+    config->pObject = PyInstance_New(config->pClass, pArgs, 0);
+    Py_DECREF(pArgs);
+
+    if (config->pObject == 0) {
+        qd_error_py();
+        Py_DECREF(config->pModule);
+        free_qd_config_t(config);
+        return 0;
+    }
+
+    return config;
+}
+
+
+qd_error_t qd_config_read(qd_config_t *config, const char *filepath)
+{
+    qd_error_clear();
+    PyObject *pMethod;
+    PyObject *pPath;
+    PyObject *pArgs;
+    PyObject *pResult;
+
+    if (!config)
+	return qd_error(QD_ERROR_CONFIG, "No configuration object");
+
+    pMethod = PyObject_GetAttrString(config->pObject, "read_file");
+    if (!pMethod || !PyCallable_Check(pMethod)) {
+	Py_XDECREF(pMethod);
+        qd_error_py();
+        return qd_error(QD_ERROR_CONFIG, "No callable 'read_file'");
+    }
+
+    pArgs = PyTuple_New(1);
+    pPath = PyString_FromString(filepath);
+    PyTuple_SetItem(pArgs, 0, pPath);
+    pResult = PyObject_CallObject(pMethod, pArgs);
+    Py_DECREF(pArgs);
+    if (pResult) {
+        Py_DECREF(pResult);
+    } else {
+        return qd_error_py();
+    }
+    Py_DECREF(pMethod);
+    return QD_ERROR_NONE;
+}
+
+
+void qd_config_extend(qd_config_t *config, const char *text)
+{
+    PyRun_SimpleString(text);
+}
+
+
+void qd_config_free(qd_config_t *config)
+{
+    if (config) {
+        Py_DECREF(config->pClass);
+        Py_DECREF(config->pModule);
+        Py_DECREF(config->pObject);
+        free_qd_config_t(config);
+    }
+}
+
+
+int qd_config_item_count(const qd_dispatch_t *dispatch, const char *section)
+{
+    const qd_config_t *config = dispatch->config;
+    PyObject *pSection;
+    PyObject *pMethod;
+    PyObject *pArgs;
+    PyObject *pResult;
+    int       result = 0;
+
+    if (!config)
+        return 0;
+
+    pMethod = PyObject_GetAttrString(config->pObject, "item_count");
+    if (!pMethod || !PyCallable_Check(pMethod)) {
+        qd_log(log_source, QD_LOG_ERROR, "Problem with configuration module: No callable 'item_count'");
+        if (pMethod) {
+            Py_DECREF(pMethod);
+        }
+        return 0;
+    }
+
+    pSection = PyString_FromString(section);
+    pArgs    = PyTuple_New(1);
+    PyTuple_SetItem(pArgs, 0, pSection);
+    pResult = PyObject_CallObject(pMethod, pArgs);
+    Py_DECREF(pArgs);
+    if (pResult && PyInt_Check(pResult))
+        result = (int) PyInt_AsLong(pResult);
+    if (pResult) {
+        Py_DECREF(pResult);
+    }
+    Py_DECREF(pMethod);
+
+    return result;
+}
+
+
+static PyObject *item_value(const qd_dispatch_t *dispatch, const char *section, int index, const char* key, const char* method)
+{
+    const qd_config_t *config = dispatch->config;
+    PyObject *pSection;
+    PyObject *pIndex;
+    PyObject *pKey;
+    PyObject *pMethod;
+    PyObject *pArgs;
+    PyObject *pResult;
+
+    if (!config)
+        return 0;
+
+    pMethod = PyObject_GetAttrString(config->pObject, method);
+    if (!pMethod || !PyCallable_Check(pMethod)) {
+        qd_log(log_source, QD_LOG_ERROR, "Problem with configuration module: No callable '%s'", method);
+        if (pMethod) {
+            Py_DECREF(pMethod);
+        }
+        return 0;
+    }
+
+    pSection = PyString_FromString(section);
+    pIndex   = PyInt_FromLong((long) index);
+    pKey     = PyString_FromString(key);
+    pArgs    = PyTuple_New(3);
+    PyTuple_SetItem(pArgs, 0, pSection);
+    PyTuple_SetItem(pArgs, 1, pIndex);
+    PyTuple_SetItem(pArgs, 2, pKey);
+    pResult = PyObject_CallObject(pMethod, pArgs);
+    Py_DECREF(pArgs);
+    Py_DECREF(pMethod);
+
+    return pResult;
+}
+
+
+bool qd_config_item_exists(const qd_dispatch_t *dispatch, const char *section, int index, const char* key)
+{
+    PyObject *pResult = item_value(dispatch, section, index, key, "value_string");
+    bool exists = pResult && pResult != Py_None;
+    if (pResult) {
+        Py_DECREF(pResult);
+    }
+    return exists;
+}
+
+char *qd_config_item_value_string(const qd_dispatch_t *dispatch, const char *section, int index, const char* key)
+{
+    PyObject *pResult = item_value(dispatch, section, index, key, "value_string");
+    char     *value   = 0;
+
+    if (pResult && PyString_Check(pResult)) {
+        Py_ssize_t size = PyString_Size(pResult);
+        value = (char*) malloc(size + 1);
+        strncpy(value, PyString_AsString(pResult), size + 1);
+    }
+
+    if (pResult) {
+        Py_DECREF(pResult);
+    }
+
+    return value;
+}
+
+
+uint32_t qd_config_item_value_int(const qd_dispatch_t *dispatch, const char *section, int index, const char* key)
+{
+    PyObject *pResult = item_value(dispatch, section, index, key, "value_int");
+    uint32_t  value   = 0;
+
+    if (pResult && PyLong_Check(pResult))
+        value = (uint32_t) PyLong_AsLong(pResult);
+
+    if (pResult) {
+        Py_DECREF(pResult);
+    }
+
+    return value;
+}
+
+
+int qd_config_item_value_bool(const qd_dispatch_t *dispatch, const char *section, int index, const char* key)
+{
+    PyObject *pResult = item_value(dispatch, section, index, key, "value_bool");
+    int       value   = 0;
+
+    if (pResult && pResult != Py_None)
+        value = 1;
+
+    if (pResult) {
+        Py_DECREF(pResult);
+    }
+
+    return value;
+}

Copied: qpid/dispatch/trunk/src/config_private.h (from r1608937, qpid/dispatch/trunk/src/log_private.h)
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/config_private.h?p2=qpid/dispatch/trunk/src/config_private.h&p1=qpid/dispatch/trunk/src/log_private.h&r1=1608937&r2=1608943&rev=1608943&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/log_private.h (original)
+++ qpid/dispatch/trunk/src/config_private.h Tue Jul  8 20:30:42 2014
@@ -1,5 +1,5 @@
-#ifndef __log_private_h__
-#define __log_private_h__ 1
+#ifndef __config_private_h__
+#define __config_private_h__ 1
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -19,10 +19,15 @@
  * under the License.
  */
 
-#include <qpid/dispatch/log.h>
+#include <qpid/dispatch/config.h>
+#include <qpid/dispatch/error.h>
+#include "dispatch_private.h"
 
-void qd_log_initialize(void);
-void qd_log_finalize(void);
+void qd_config_initialize(void);
+void qd_config_finalize(void);
+qd_config_t *qd_config(void);
+qd_error_t qd_config_read(qd_config_t *config, const char *filename);
+void qd_config_extend(qd_config_t *config, const char *text);
+void qd_config_free(qd_config_t *config);
 
-#define QD_LOG_TEXT_MAX 2048
 #endif

Modified: qpid/dispatch/trunk/src/connection_manager.c
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/connection_manager.c?rev=1608943&r1=1608942&r2=1608943&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/connection_manager.c (original)
+++ qpid/dispatch/trunk/src/connection_manager.c Tue Jul  8 20:30:42 2014
@@ -22,10 +22,12 @@
 #include <qpid/dispatch/agent.h>
 #include "dispatch_private.h"
 #include "server_private.h"
-#include "entity_private.h"
-#include "schema_enum.h"
 #include <string.h>
 
+static const char *CONF_LISTENER    = "listener";
+static const char *CONF_CONNECTOR   = "connector";
+
+
 struct qd_config_listener_t {
     DEQ_LINKS(qd_config_listener_t);
     qd_listener_t      *listener;
@@ -56,95 +58,93 @@ struct qd_connection_manager_t {
 };
 
 
-// True if entity has any of attributes.
-static bool has_attrs(qd_entity_t *entity, const char **attributes, int n) {
-    for (int i = 0; i < n; ++i)
-	if (qd_entity_has(entity, attributes[i])) return true;
-    return false;
-}
-
-static const char *ssl_attributes[] = {
-    "allow-unsecured", "cert-file", "key-file", "password", "cert-db",
-    "trusted-certs", "require-peer-auth"
-};
-static const int ssl_attributes_count = sizeof(ssl_attributes)/sizeof(ssl_attributes[0]);
-
-static void qd_server_config_free(qd_server_config_t *cf)
-{
-    if (!cf) return;
-    free(cf->host);
-    free(cf->port);
-    free(cf->role);
-    free(cf->sasl_mechanisms);
-    if (cf->ssl_enabled) {
-        free(cf->ssl_certificate_file);
-        free(cf->ssl_private_key_file);
-        free(cf->ssl_password);
-        free(cf->ssl_trusted_certificate_db);
-        free(cf->ssl_trusted_certificates);
-    }
-    memset(cf, 0, sizeof(*cf));
-}
-
-#define CHECK() if (qd_error_code()) goto error
-static qd_error_t load_server_config(qd_dispatch_t *qd, qd_server_config_t *config, qd_entity_t* entity)
+static void load_server_config(qd_dispatch_t *qd, qd_server_config_t *config, const char *section, int i)
 {
-    qd_error_clear();
-    memset(config, 0, sizeof(*config));
-    config->host           = qd_entity_string(entity, "addr"); CHECK();
-    config->port           = qd_entity_string(entity, "port"); CHECK();
-    config->role           = qd_entity_string(entity, "role"); CHECK();
-    config->max_frame_size = qd_entity_long(entity, "max-frame-size"); CHECK();
-    config->sasl_mechanisms = qd_entity_string(entity, "sasl-mechanisms"); CHECK();
-    config->ssl_enabled = has_attrs(entity, ssl_attributes, ssl_attributes_count);
+    config->host           = qd_config_item_value_string(qd, section, i, "addr");
+    config->port           = qd_config_item_value_string(qd, section, i, "port");
+    config->role           = qd_config_item_value_string(qd, section, i, "role");
+    config->max_frame_size = qd_config_item_value_int(qd, section, i, "max-frame-size");
+    config->sasl_mechanisms =
+        qd_config_item_value_string(qd, section, i, "sasl-mechanisms");
+    config->ssl_enabled =
+        qd_config_item_value_bool(qd, section, i, "ssl-profile");
     if (config->ssl_enabled) {
         config->ssl_server = 1;
-	config->ssl_allow_unsecured_client = qd_entity_opt_bool(entity, "allow-unsecured", false); CHECK();
-	config->ssl_certificate_file = qd_entity_opt_string(entity, "cert-file", 0); CHECK();
-	config->ssl_private_key_file = qd_entity_opt_string(entity, "key-file", 0); CHECK();
-	config->ssl_trusted_certificate_db = qd_entity_opt_string(entity, "cert-db", 0); CHECK();
-	config->ssl_trusted_certificates = qd_entity_opt_string(entity, "trusted-certs", 0); CHECK();
+        config->ssl_allow_unsecured_client =
+            qd_config_item_value_bool(qd, section, i, "allow-unsecured");
+        config->ssl_certificate_file =
+            qd_config_item_value_string(qd, section, i, "cert-file");
+        config->ssl_private_key_file =
+            qd_config_item_value_string(qd, section, i, "key-file");
+        config->ssl_password =
+            qd_config_item_value_string(qd, section, i, "password");
+        config->ssl_trusted_certificate_db =
+            qd_config_item_value_string(qd, section, i, "cert-db");
+        config->ssl_trusted_certificates =
+            qd_config_item_value_string(qd, section, i, "trusted-certs");
+        config->ssl_require_peer_authentication =
+            qd_config_item_value_bool(qd, section, i, "require-peer-auth");
     }
-    return QD_ERROR_NONE;
-
-  error:
-    qd_server_config_free(config);
-    return qd_error_code();
 }
 
-void qd_dispatch_configure_listener(qd_dispatch_t *qd, qd_entity_t *entity)
+
+static void configure_listeners(qd_dispatch_t *qd)
 {
+    int count;
     qd_connection_manager_t *cm = qd->connection_manager;
-    qd_config_listener_t *cl = NEW(qd_config_listener_t);
-    cl->listener = 0;
-    load_server_config(qd, &cl->configuration, entity);
-    DEQ_ITEM_INIT(cl);
-    DEQ_INSERT_TAIL(cm->config_listeners, cl);
-    qd_log(cm->log_source, QD_LOG_INFO, "Configured Listener: %s:%s role=%s",
-	   cl->configuration.host, cl->configuration.port, cl->configuration.role);
+
+    if (!qd->config || !cm) {
+        qd_log(cm->log_source, QD_LOG_ERROR, "Cannot configure listeners%s%s",
+	       (qd->config ? "" : ", no configuration"),
+	       (cm ? "" : ", no connection manager"));
+        assert(false);
+        return;
+    }
+
+    count = qd_config_item_count(qd, CONF_LISTENER);
+    for (int i = 0; i < count; i++) {
+        qd_config_listener_t *cl = NEW(qd_config_listener_t);
+        cl->listener = 0;
+        load_server_config(qd, &cl->configuration, CONF_LISTENER, i);
+        DEQ_ITEM_INIT(cl);
+        DEQ_INSERT_TAIL(cm->config_listeners, cl);
+        qd_log(cm->log_source, QD_LOG_INFO, "Configured Listener: %s:%s role=%s",
+               cl->configuration.host, cl->configuration.port, cl->configuration.role);
+    }
 }
 
 
-qd_error_t qd_dispatch_configure_connector(qd_dispatch_t *qd, qd_entity_t *entity)
+static void configure_connectors(qd_dispatch_t *qd)
 {
-    qd_error_clear();
+    int count;
     qd_connection_manager_t *cm = qd->connection_manager;
-    qd_config_connector_t *cc = NEW(qd_config_connector_t);
-    memset(cc, 0, sizeof(*cc));
-    if (load_server_config(qd, &cc->configuration, entity))
-	return qd_error_code();
-    DEQ_ITEM_INIT(cc);
-    if (strcmp(cc->configuration.role, "on-demand") == 0) {
-	cc->connector_name = qd_entity_string(entity, "name"); QD_ERROR_RET();
-	DEQ_INSERT_TAIL(cm->on_demand_connectors, cc);
-	qd_log(cm->log_source, QD_LOG_INFO, "Configured on-demand connector: %s:%s name=%s",
-	       cc->configuration.host, cc->configuration.port, cc->connector_name);
-    } else {
-	DEQ_INSERT_TAIL(cm->config_connectors, cc);
-	qd_log(cm->log_source, QD_LOG_INFO, "Configured Connector: %s:%s role=%s",
-	       cc->configuration.host, cc->configuration.port, cc->configuration.role);
+
+    if (!qd->config || !cm) {
+        assert(false);
+        return;
+    }
+
+    count = qd_config_item_count(qd, CONF_CONNECTOR);
+    for (int i = 0; i < count; i++) {
+        qd_config_connector_t *cc = NEW(qd_config_connector_t);
+        cc->context        = 0;
+        cc->connector      = 0;
+        cc->connector_name = 0;
+        cc->started        = false;
+        load_server_config(qd, &cc->configuration, CONF_CONNECTOR, i);
+        DEQ_ITEM_INIT(cc);
+        if (strcmp(cc->configuration.role, "on-demand") == 0) {
+            cc->connector_name =
+                qd_config_item_value_string(qd, CONF_CONNECTOR, i, "name");
+            DEQ_INSERT_TAIL(cm->on_demand_connectors, cc);
+            qd_log(cm->log_source, QD_LOG_INFO, "Configured on-demand connector: %s:%s name=%s",
+                   cc->configuration.host, cc->configuration.port, cc->connector_name);
+        } else {
+            DEQ_INSERT_TAIL(cm->config_connectors, cc);
+            qd_log(cm->log_source, QD_LOG_INFO, "Configured Connector: %s:%s role=%s",
+                   cc->configuration.host, cc->configuration.port, cc->configuration.role);
+        }
     }
-    return QD_ERROR_NONE;
 }
 
 
@@ -164,6 +164,23 @@ qd_connection_manager_t *qd_connection_m
 }
 
 
+static void qd_connection_manager_config_free(qd_server_config_t *cf)
+{
+    if (!cf) return;
+    free(cf->host);
+    free(cf->port);
+    free(cf->role);
+    free(cf->sasl_mechanisms);
+    if (cf->ssl_enabled) {
+        free(cf->ssl_certificate_file);
+        free(cf->ssl_private_key_file);
+        free(cf->ssl_password);
+        free(cf->ssl_trusted_certificate_db);
+        free(cf->ssl_trusted_certificates);
+    }
+}
+
+
 void qd_connection_manager_free(qd_connection_manager_t *cm)
 {
     if (!cm) return;
@@ -171,7 +188,7 @@ void qd_connection_manager_free(qd_conne
     while (cl) {
         DEQ_REMOVE_HEAD(cm->config_listeners);
         qd_server_listener_free(cl->listener);
-        qd_server_config_free(&cl->configuration);
+        qd_connection_manager_config_free(&cl->configuration);
         free(cl);
         cl = DEQ_HEAD(cm->config_listeners);
     }
@@ -180,7 +197,7 @@ void qd_connection_manager_free(qd_conne
     while(cc) {
         DEQ_REMOVE_HEAD(cm->config_connectors);
         qd_server_connector_free(cc->connector);
-        qd_server_config_free(&cc->configuration);
+        qd_connection_manager_config_free(&cc->configuration);
         free(cc);
         cc = DEQ_HEAD(cm->config_connectors);
     }
@@ -190,13 +207,20 @@ void qd_connection_manager_free(qd_conne
         DEQ_REMOVE_HEAD(cm->on_demand_connectors);
         if (odc->connector)
             qd_server_connector_free(odc->connector);
-        qd_server_config_free(&odc->configuration);
+        qd_connection_manager_config_free(&odc->configuration);
         free(odc);
         odc = DEQ_HEAD(cm->on_demand_connectors);
     }
 }
 
 
+void qd_connection_manager_configure(qd_dispatch_t *qd)
+{
+    configure_listeners(qd);
+    configure_connectors(qd);
+}
+
+
 void qd_connection_manager_start(qd_dispatch_t *qd)
 {
     qd_config_listener_t  *cl = DEQ_HEAD(qd->connection_manager->config_listeners);

Modified: qpid/dispatch/trunk/src/dispatch.c
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/dispatch.c?rev=1608943&r1=1608942&r2=1608943&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/dispatch.c (original)
+++ qpid/dispatch/trunk/src/dispatch.c Tue Jul  8 20:30:42 2014
@@ -27,8 +27,6 @@
 #include "router_private.h"
 #include "waypoint_private.h"
 #include "message_private.h"
-#include "entity_private.h"
-#include "static_assert.h"
 
 /**
  * Private Function Prototypes
@@ -46,79 +44,94 @@ qd_agent_t     *qd_agent(qd_dispatch_t *
 void            qd_agent_free(qd_agent_t *agent);
 void            qd_error_initialize();
 
-qd_dispatch_t *qd_dispatch(const char *python_pkgdir, const char *qpid_dispatch_lib)
+static const char *CONF_CONTAINER   = "container";
+static const char *CONF_ROUTER      = "router";
+
+
+qd_dispatch_t *qd_dispatch(const char *python_pkgdir)
 {
-    qd_error_clear();
     qd_dispatch_t *qd = NEW(qd_dispatch_t);
+
     memset(qd, 0, sizeof(qd_dispatch_t));
 
     // alloc, log and error have to be initialized before any module.
     qd_alloc_initialize();
     qd_log_initialize();
     qd_error_initialize();
-    if (qd_error_code()) return 0;
 
     qd->router_area = strdup("0");
     qd->router_id   = strdup("0");
     qd->router_mode = QD_ROUTER_MODE_ENDPOINT;
 
-    qd_python_initialize(qd, python_pkgdir, qpid_dispatch_lib);
-    if (qd_error_code()) { qd_dispatch_free(qd); return 0; }
+    qd_python_initialize(qd, python_pkgdir);
+    qd_config_initialize();
     qd_message_initialize();
-    if (qd_error_code()) { qd_dispatch_free(qd); return 0; }
+    qd->config = qd_config();
+
     return qd;
 }
 
 
-// We pass pointers as longs via the python interface, make sure this is safe.
-STATIC_ASSERT(sizeof(long) >= sizeof(void*), pointer_is_bigger_than_long);
+void qd_dispatch_extend_config_schema(qd_dispatch_t *qd, const char* text)
+{
+    qd_config_extend(qd->config, text);
+}
+
 
 qd_error_t qd_dispatch_load_config(qd_dispatch_t *qd, const char *config_path)
 {
-    PyObject *module = 0, *configure_dispatch = 0, *result = 0;
-    bool ok =
-        (module = PyImport_ImportModule("qpid_dispatch_internal.management")) &&
-	(configure_dispatch = PyObject_GetAttrString(module, "configure_dispatch")) &&
-	(result = PyObject_CallFunction(configure_dispatch, "(ls)", (long)qd, config_path));
-    Py_XDECREF(module);
-    Py_XDECREF(configure_dispatch);
-    Py_XDECREF(result);
-    return ok ? QD_ERROR_NONE : qd_error_py();
+    return qd_config_read(qd->config, config_path);
 }
 
 
-qd_error_t qd_dispatch_configure_container(qd_dispatch_t *qd, qd_entity_t *entity)
+void qd_dispatch_configure_container(qd_dispatch_t *qd)
 {
-    const char *default_name = "00000000-0000-0000-0000-000000000000";
-    qd->thread_count   = qd_entity_opt_long(entity, "worker-threads", 1); QD_ERROR_RET();
-    qd->container_name = qd_entity_opt_string(entity, "container-name", default_name); QD_ERROR_RET();
-    return QD_ERROR_NONE;
+    if (qd->config) {
+        int count = qd_config_item_count(qd, CONF_CONTAINER);
+        if (count == 1) {
+            qd->thread_count   = qd_config_item_value_int(qd, CONF_CONTAINER, 0, "worker-threads");
+            qd->container_name = qd_config_item_value_string(qd, CONF_CONTAINER, 0, "container-name");
+        }
+    }
+
+    if (qd->thread_count == 0)
+        qd->thread_count = 1;
+
+    if (!qd->container_name)
+        qd->container_name = "00000000-0000-0000-0000-000000000000";  // TODO - gen a real uuid
 }
 
 
-qd_error_t qd_dispatch_configure_router(qd_dispatch_t *qd, qd_entity_t *entity)
+void qd_dispatch_configure_router(qd_dispatch_t *qd)
 {
-    qd_error_clear();
-    free(qd->router_id);
-    qd->router_id   = qd_entity_opt_string(entity, "router-id", qd->container_name);
-    QD_ERROR_RET();
-    qd->router_mode = qd_entity_long(entity, "mode");
-    return qd_error_code();
-}
+    char *router_mode_str = 0;
 
-qd_error_t qd_dispatch_configure_address(qd_dispatch_t *qd, qd_entity_t *entity) {
-    if (!qd->router) return qd_error(QD_ERROR_NOT_FOUND, "No router available");
-    qd_router_configure_address(qd->router, entity);
-    return qd_error_code();
-}
+    if (qd->config) {
+        int count = qd_config_item_count(qd, CONF_ROUTER);
+        if (count == 1) {
+            router_mode_str = qd_config_item_value_string(qd, CONF_ROUTER, 0, "mode");
+            free(qd->router_id);
+            qd->router_id   = qd_config_item_value_string(qd, CONF_ROUTER, 0, "router-id");
+        }
+    }
+
+    if (router_mode_str && strcmp(router_mode_str, "standalone") == 0)
+        qd->router_mode = QD_ROUTER_MODE_STANDALONE;
+
+    if (router_mode_str && strcmp(router_mode_str, "interior") == 0)
+        qd->router_mode = QD_ROUTER_MODE_INTERIOR;
+
+    if (router_mode_str && strcmp(router_mode_str, "edge") == 0)
+        qd->router_mode = QD_ROUTER_MODE_EDGE;
+
+    if (!qd->router_id)
+        qd->router_id = qd->container_name;
 
-qd_error_t qd_dispatch_configure_waypoint(qd_dispatch_t *qd, qd_entity_t *entity) {
-    if (!qd->router) return qd_error(QD_ERROR_NOT_FOUND, "No router available");
-    qd_router_configure_waypoint(qd->router, entity);
-    return qd_error_code();
+    free(router_mode_str);
 }
 
-qd_error_t qd_dispatch_prepare(qd_dispatch_t *qd)
+
+void qd_dispatch_prepare(qd_dispatch_t *qd)
 {
     qd->server             = qd_server(qd->thread_count, qd->container_name);
     qd->container          = qd_container(qd);
@@ -130,7 +143,6 @@ qd_error_t qd_dispatch_prepare(qd_dispat
     qd_connection_manager_setup_agent(qd);
     qd_container_setup_agent(qd);
     qd_router_setup_late(qd);
-    return qd_error_code();
 }
 
 
@@ -138,8 +150,9 @@ void qd_dispatch_free(qd_dispatch_t *qd)
 {
     if (!qd) return;
     free(qd->router_id);
-    free(qd->container_name);
     free(qd->router_area);
+    qd_config_free(qd->config);
+    qd_config_finalize();
     qd_connection_manager_free(qd->connection_manager);
     qd_agent_free(qd->agent);
     qd_router_free(qd->router);
@@ -149,3 +162,11 @@ void qd_dispatch_free(qd_dispatch_t *qd)
     qd_alloc_finalize();
     qd_python_finalize();
 }
+
+
+void qd_dispatch_post_configure_connections(qd_dispatch_t *qd)
+{
+    qd_connection_manager_configure(qd);
+    qd_connection_manager_start(qd);
+    qd_waypoint_activate_all(qd);
+}

Modified: qpid/dispatch/trunk/src/dispatch_private.h
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/dispatch_private.h?rev=1608943&r1=1608942&r2=1608943&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/dispatch_private.h (original)
+++ qpid/dispatch/trunk/src/dispatch_private.h Tue Jul  8 20:30:42 2014
@@ -28,6 +28,7 @@ typedef struct qd_container_t       qd_c
 typedef struct qd_router_t          qd_router_t;
 typedef struct qd_agent_t           qd_agent_t;
 typedef struct qd_waypoint_t        qd_waypoint_t;
+typedef struct qd_config_t          qd_config_t;
 typedef struct qd_router_link_t     qd_router_link_t;
 typedef struct qd_router_node_t     qd_router_node_t;
 typedef struct qd_router_ref_t      qd_router_ref_t;
@@ -41,6 +42,7 @@ typedef struct qd_config_address_t  qd_c
 #include <qpid/dispatch/router.h>
 #include <qpid/dispatch/connection_manager.h>
 #include "server_private.h"
+#include "config_private.h"
 #include "router_private.h"
 
 
@@ -49,6 +51,7 @@ struct qd_dispatch_t {
     qd_container_t          *container;
     qd_router_t             *router;
     qd_agent_t              *agent;
+    qd_config_t             *config;
     qd_connection_manager_t *connection_manager;
 
     int    thread_count;
@@ -59,3 +62,4 @@ struct qd_dispatch_t {
 };
 
 #endif
+

Modified: qpid/dispatch/trunk/src/error.c
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/error.c?rev=1608943&r1=1608942&r2=1608943&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/error.c (original)
+++ qpid/dispatch/trunk/src/error.c Tue Jul  8 20:30:42 2014
@@ -32,13 +32,10 @@ static const char *error_names[] = {
  "Allocation",
  "Invalid message",
  "Python",
- "Configuration",
- "Type",
- "Value"
+ "Configuration"
 };
 
-STATIC_ASSERT(sizeof(error_names)/sizeof(error_names[0]) == QD_ERROR_ENUM_COUNT,
-	      error_names_wrong_size);
+STATIC_ASSERT(sizeof(error_names)/sizeof(error_names[0]) == QD_ERROR_COUNT, error_names_wrong_size);
 
 #define ERROR_MAX QD_LOG_TEXT_MAX
 const int QD_ERROR_MAX = ERROR_MAX;
@@ -59,7 +56,7 @@ qd_error_t qd_error(qd_error_t code, con
     ts.error_code = code;
     if (code) {
 	int i = 0;
-	if (code < QD_ERROR_ENUM_COUNT)
+	if (code < QD_ERROR_COUNT)
 	    i = snprintf(ts.error_message, ERROR_MAX,"%s: ", error_names[code]);
 	else
 	    i = snprintf(ts.error_message, ERROR_MAX, "%d: ", code);
@@ -94,11 +91,17 @@ static void py_set_item(PyObject *dict, 
     Py_DECREF(py_name);
 }
 
-static void log_trace_py(PyObject *type, PyObject *value, PyObject* trace, qd_log_level_t level) {
-    if (!qd_log_enabled(log_source, level)) return;
+static PyObject *py_import(const char* module) {
+    PyObject *py_str = PyString_FromString(module);
+    PyObject *py_module = PyImport_Import(py_str);
+    Py_DECREF(py_str);
+    return py_module;
+}
+
+static void log_trace_py(PyObject *type, PyObject *value, PyObject* trace) {
     if (!(type && value && trace)) return;
 
-    PyObject *module = PyImport_ImportModule("traceback");
+    PyObject *module = py_import("traceback");
     if (!module) return;
 
     PyObject *globals = PyDict_New();
@@ -116,21 +119,9 @@ static void log_trace_py(PyObject *type,
     Py_DECREF(locals);
 
     if (result) {
-	const char* trace = PyString_AsString(result);
-	if (strlen(trace) < QD_LOG_TEXT_MAX) {
-	    qd_log(log_source, level, "%s", trace);
-	} else {
-	    // Keep as much of the the tail of the trace as we can.
-	    const char *tail = trace;
-	    while (tail && strlen(tail) > QD_LOG_TEXT_MAX) {
-		tail = strchr(tail, '\n');
-		if (tail) ++tail;
-	    }
-	    qd_log(log_source, level, "Traceback truncated:\n%s", tail ? tail : "");
-	}
+	qd_log(log_source, QD_LOG_ERROR, "%s", PyString_AsString(result));
 	Py_DECREF(result);
     }
-
 }
 
 qd_error_t qd_error_py() {
@@ -149,7 +140,7 @@ qd_error_t qd_error_py() {
 	Py_XDECREF(value_str);
 	Py_XDECREF(type_name);
 
-	log_trace_py(type, value, trace, QD_LOG_ERROR);
+	log_trace_py(type, value, trace);
 
 	Py_XDECREF(type);
 	Py_XDECREF(value);

Modified: qpid/dispatch/trunk/src/log.c
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/log.c?rev=1608943&r1=1608942&r2=1608943&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/log.c (original)
+++ qpid/dispatch/trunk/src/log.c Tue Jul  8 20:30:42 2014
@@ -18,7 +18,7 @@
  */
 
 #include "log_private.h"
-#include "entity_private.h"
+#include <qpid/dispatch/config.h>
 #include <qpid/dispatch/ctools.h>
 #include <qpid/dispatch/dispatch.h>
 #include <qpid/dispatch/alloc.h>
@@ -312,7 +312,7 @@ void qd_log_initialize(void)
 
     default_log_source = qd_log_source(SOURCE_DEFAULT);
     // Only report errors until we have configured the logging system.
-    default_log_source->mask = levels[INFO].mask;
+    default_log_source->mask = levels[ERROR].mask;
     default_log_source->timestamp = 1;
     default_log_source->sink = log_sink_lh(SINK_STDERR);
     logging_log_source = qd_log_source(SOURCE_LOGGING);
@@ -328,36 +328,37 @@ void qd_log_finalize(void) {
 	log_sink_free_lh(DEQ_HEAD(sink_list));
 }
 
-qd_error_t qd_log_entity(qd_entity_t *entity) {
+///@return 0,1 or -1 if not present
+static int get_optional_bool(const qd_dispatch_t *qd, const char* item, int i, const char* name) {
+    if (!qd_config_item_exists(qd, item, i, name)) return -1;
+    return qd_config_item_value_bool(qd, item, i, name);
+}
 
-    qd_error_clear();
-    char* module = qd_entity_string(entity, "module"); QD_ERROR_RET();
-    sys_mutex_lock(log_source_lock);
-    qd_log_source_t *src = qd_log_source_lh(module);
-    assert(src);
-    qd_log_source_t copy = *src;
-    sys_mutex_unlock(log_source_lock);
-    free(module);
+#define ITEM_STRING(NAME) qd_config_item_value_string(qd, "log", i, NAME)
+#define ITEM_OPT_BOOL(NAME) get_optional_bool(qd, "log", i, NAME)
 
-    char *level = qd_entity_string(entity, "level"); QD_ERROR_RET();
-    copy.mask = level_for_name(level)->mask;
-    free(level);
-
-    if (qd_entity_has(entity, "timestamp"))
-	copy.timestamp = qd_entity_bool(entity, "timestamp");
-    QD_ERROR_RET();
-
-    if (qd_entity_has(entity, "output")) {
-	log_sink_free_lh(copy.sink); /* DEFAULT source may already have a sink */
-	char* output = qd_entity_string(entity, "output"); QD_ERROR_RET();
-	copy.sink = log_sink_lh(output);
-	free(output);
-	if (copy.sink->syslog) /* Timestamp off for syslog. */
-	    copy.timestamp = 0;
+void qd_log_configure(const qd_dispatch_t *qd)
+{
+    if (!qd) return;
+    // Default to INFO now that we are configuring the logging system.
+    default_log_source->mask = levels[INFO].mask;
+    int count = qd_config_item_count(qd, "log");
+    for (int i=0; i < count; i++) {
+	sys_mutex_lock(log_source_lock);
+	const char* module = ITEM_STRING("module");
+	qd_log_source_t *src = qd_log_source_lh(module);
+	src->mask = level_for_name(ITEM_STRING("level"))->mask;
+	int timestamp = ITEM_OPT_BOOL("timestamp");
+	if (timestamp != -1) src->timestamp = timestamp;
+	const char* output = ITEM_STRING("output");
+	if (output) {
+	    log_sink_t* old_sink = src->sink;
+	    src->sink = log_sink_lh(output);
+	    log_sink_free_lh(old_sink); /* DEFAULT source may already have a sink */
+	    if (src->sink->syslog) /* Timestamp off for syslog. */
+		src->timestamp = 0;
+	}
+	sys_mutex_unlock(log_source_lock);
     }
-
-    sys_mutex_lock(log_source_lock);
-    *src = copy;
-    sys_mutex_unlock(log_source_lock);
-    return qd_error_code();
+    qd_log(logging_log_source, QD_LOG_INFO, "Logging system configured");
 }

Modified: qpid/dispatch/trunk/src/log_private.h
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/log_private.h?rev=1608943&r1=1608942&r2=1608943&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/log_private.h (original)
+++ qpid/dispatch/trunk/src/log_private.h Tue Jul  8 20:30:42 2014
@@ -23,6 +23,5 @@
 
 void qd_log_initialize(void);
 void qd_log_finalize(void);
-
-#define QD_LOG_TEXT_MAX 2048
+#define QD_LOG_TEXT_MAX 1024
 #endif



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