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