You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by tr...@apache.org on 2016/03/15 19:32:43 UTC

[3/4] qpid-dispatch git commit: DISPATCH-179 - Significant update to the management model for routes. Removed the singular "route" configuration and replaced it with three distinct object types: address, linkRoute, and autoLink.

DISPATCH-179 - Significant update to the management model for routes.
Removed the singular "route" configuration and replaced it with three
distinct object types: address, linkRoute, and autoLink.


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

Branch: refs/heads/tross-DISPATCH-179-1
Commit: ab2734f9bf6761abfb1f54b26fd779a5f06961d9
Parents: 5c839b3
Author: Ted Ross <tr...@redhat.com>
Authored: Tue Mar 15 14:15:21 2016 -0400
Committer: Ted Ross <tr...@redhat.com>
Committed: Tue Mar 15 14:15:21 2016 -0400

----------------------------------------------------------------------
 include/qpid/dispatch/router_core.h             |  28 +-
 python/qpid_dispatch/management/qdrouter.json   | 162 ++++---
 python/qpid_dispatch_internal/dispatch.py       |   6 +-
 .../qpid_dispatch_internal/management/agent.py  |  56 ++-
 src/CMakeLists.txt                              |   2 +-
 src/dispatch.c                                  |  20 +-
 src/router_config.c                             | 251 +++++++----
 src/router_core/agent.c                         | 115 +++--
 src/router_core/agent_config_address.c          | 415 ++++++++++++++++++
 src/router_core/agent_config_address.h          |  35 ++
 src/router_core/agent_route.c                   | 421 -------------------
 src/router_core/agent_route.h                   |  35 --
 src/router_core/management_agent.c              |  45 +-
 src/router_core/route_control.c                 | 331 +++++----------
 src/router_core/route_control.h                 |  38 +-
 src/router_core/router_core_private.h           |  83 ++--
 src/router_private.h                            |   6 +-
 17 files changed, 1052 insertions(+), 997 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/ab2734f9/include/qpid/dispatch/router_core.h
----------------------------------------------------------------------
diff --git a/include/qpid/dispatch/router_core.h b/include/qpid/dispatch/router_core.h
index 16aa513..271954b 100644
--- a/include/qpid/dispatch/router_core.h
+++ b/include/qpid/dispatch/router_core.h
@@ -544,7 +544,9 @@ qd_message_t *qdr_delivery_message(const qdr_delivery_t *delivery);
  ******************************************************************************
  */
 typedef enum {
-    QD_ROUTER_ROUTE,
+    QD_ROUTER_CONFIG_ADDRESS,
+    QD_ROUTER_CONFIG_LINK_ROUTE,
+    QD_ROUTER_CONFIG_AUTO_LINK,
     QD_ROUTER_CONNECTION,
     QD_ROUTER_LINK,
     QD_ROUTER_ADDRESS,
@@ -617,30 +619,6 @@ void qdr_manage_update(qdr_core_t *core, void *context, qd_router_entity_type_t
                        qd_parsed_field_t *in_body, qd_composed_field_t *out_body);
 
 /**
- * qdr_manage_method
- *
- * Invoke a custom method on a managed entity in the router core.
- *
- * @param core Pointer to the core object returned by qd_core()
- * @param context An opaque context that will be passed back in the invocation of the response callback
- * @param type The entity type for the update request
- * @param method The method being invoked
- * @param name The name supplied with the request (or 0 if the identity was supplied)
- * @param identity The identity supplied with the request (or 0 if the name was supplied)
- * @param in_body The body of the request message
- * @param out_body A composed field for the body of the response message
- */
-void qdr_manage_method(qdr_core_t              *core,
-                       void                    *context,
-                       qd_router_entity_type_t  type,
-                       qd_field_iterator_t     *method,
-                       qd_field_iterator_t     *name,
-                       qd_field_iterator_t     *identity,
-                       qd_parsed_field_t       *in_body,
-                       qd_composed_field_t     *out_body);
-
-
-/**
  * Sequence for running a query:
  *
  * 1) Locate the attributeNames field in the body of the QUERY request

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/ab2734f9/python/qpid_dispatch/management/qdrouter.json
----------------------------------------------------------------------
diff --git a/python/qpid_dispatch/management/qdrouter.json b/python/qpid_dispatch/management/qdrouter.json
index 327e504..40f3e19 100644
--- a/python/qpid_dispatch/management/qdrouter.json
+++ b/python/qpid_dispatch/management/qdrouter.json
@@ -829,46 +829,125 @@
             }
         },
 
-        "route": {
-            "description": "Provisioned route that affects the treatment of message deliveries and link attaches",
+        "router.config.address": {
+            "description": "Entity type for address configuration.  This is used to configure the treatment of message-routed deliveries within a particular address-space.  The configuration controls distribution and address phasing.",
             "extends": "configurationEntity",
-            "operations": ["CREATE", "DELETE", "ADD-CONTAINER", "REMOVE-CONTAINER-CLEAN", "REMOVE-CONTAINER-HARD"],
+            "operations": ["CREATE", "DELETE"],
             "attributes": {
-                "address": {
+                "prefix": {
                     "type": "string",
-                    "description": "The address or address prefix for the provisioned object",
+                    "description": "The address prefix for the configured settings",
                     "create": true,
                     "required": true
                 },
-                "path": {
-                    "type": ["direct", "source", "sink", "waypoint"],
-                    "description": "Type of object being provisioned:  address prefix, link destination, or waypoint",
+                "distribution": {
+                    "type": ["multicast", "closest", "balanced"],
+                    "description": "Treatment of traffic associated with the address",
                     "create": true,
-                    "default": "direct"
+                    "required": false,
+                    "default": "balanced"
                 },
-                "treatment": {
-                    "type": ["multicast", "closest", "balanced", "linkBalanced"],
+                "waypoint": {
+                    "type": "boolean",
+                    "description": "Designates this address space as being used for waypoints.  This will cause the proper address-phasing to be used.",
+                    "create": true,
+                    "required": false,
+                    "default": false
+                },
+                "ingressPhase": {
+                    "type": "integer",
+                    "description": "Advanced - Override the ingress phase for this address",
+                    "create": true,
+                    "required": false
+                },
+                "egressPhase": {
+                    "type": "integer",
+                    "description": "Advanced - Override the egress phase for this address",
+                    "create": true,
+                    "required": false
+                }
+            }
+        },
+
+        "router.config.linkRoute": {
+            "description": "Entity type for link-route configuration.  This is used to identify remote containers that shall be destinations for routed link-attaches.  The link-routing configuration applies to an addressing space defined by a prefix.",
+            "extends": "configurationEntity",
+            "operations": ["CREATE", "DELETE"],
+            "attributes": {
+                "prefix": {
+                    "type": "string",
+                    "description": "The address prefix for the configured settings",
+                    "create": true,
+                    "required": true
+                },
+                "containerId": {
+                    "type": "string",
+                    "description": "ContainerID for the target container",
+                    "create": true,
+                    "required": false
+                },
+                "connectionName": {
+                    "type": "string",
+                    "description": "The name from a connector or listener",
+                    "create": true,
+                    "required": false
+                },
+                "distribution": {
+                    "type": ["linkBalanced"],
                     "description": "Treatment of traffic associated with the address",
                     "create": true,
-                    "default": "balanced"
+                    "required": false,
+                    "default": "linkBalanced"
                 },
-                "connectors": {
+                "dir": {
+                    "type": ["in", "out"],
+                    "description": "The permitted direction of links: 'in' means client senders; 'out' means client receivers",
+                    "create": true,
+                    "required": false,
+                    "default": "both"
+                }
+            }
+        },
+
+        "router.config.autoLink": {
+            "description": "Entity type for configuring auto-links.  Auto-links are links whose lifecycle is managed by the router.  These are typically used to attach to waypoints on remote containers (brokers, etc.).",
+            "extends": "configurationEntity",
+            "operations": ["CREATE", "DELETE"],
+            "attributes": {
+                "addr": {
                     "type": "string",
-                    "description": "Comma-separated list of names associated with the connector leading to the target containers",
+                    "description": "The address or address prefix for the provisioned object",
+                    "create": true,
+                    "required": true
+                },
+                "dir": {
+                    "type": ["in", "out"],
+                    "description": "The direction of the link to be created.  In means into the router, out means out of the router.",
+                    "create": true,
+                    "required": true
+                },
+                "phase": {
+                    "type": "integer",
+                    "description": "The address phase for this link.  Defaults to '0' for 'out' links and '1' for 'in' links.",
                     "create": true,
                     "required": false
                 },
-                "containers": {
+                "containerId": {
                     "type": "string",
-                    "description": "Comma-separated list of container-IDs for target containers",
+                    "description": "ContainerID for the target container",
                     "create": true,
                     "required": false
                 },
-                "routeAddress": {
+                "connectionName": {
                     "type": "string",
-                    "description": "Alternate address to use for routing links/messages",
+                    "description": "The name from a connector or listener",
                     "create": true,
                     "required": false
+                },
+                "linkRef": {
+                    "type": "string",
+                    "description": "Reference to the org.apache.qpid.dispatch.router.link if the link is attached",
+                    "create": false
                 }
             }
         },
@@ -876,14 +955,23 @@
         "router.link": {
             "description": "Link to another AMQP endpoint: router node, client or other AMQP process.",
             "extends": "operationalEntity",
+            "operations": ["UPDATE"],
             "attributes": {
+                "adminStatus": {
+                    "type": ["enabled", "disabled"],
+                    "default": "enabled",
+                    "update": true
+                },
+                "operStatus": {
+                    "type": ["up", "down", "quiescing"]
+                },
                 "linkName": {
                     "type": "string",
                     "description": "Name assigned to the link in the Attach."
                 },
                 "linkType": {
-                    "type": ["endpoint", "waypoint", "router-control", "inter-router"],
-                    "description": "Type of link: endpoint: a link to a normally connected endpoint; waypoint: a link to a waypoint node; inter-router: a link to another router in the network."
+                    "type": ["endpoint", "router-control", "inter-router"],
+                    "description": "Type of link: endpoint: a link to a normally connected endpoint; inter-router: a link to another router in the network."
                 },
                 "linkDir": {
                     "type": ["in", "out"],
@@ -912,19 +1000,6 @@
                 "deliveryCount": {
                     "type": "integer",
                     "description": "The total number of deliveries that have traversed this link."
-                },
-                "adminState": {
-                    "type": ["enabled", "disabled"],
-                    "description": "",
-                    "default": "enabled",
-                    "create": false,
-                    "update": true
-                },
-                "operState": {
-                    "type": ["attaching", "up", "quiescing", "stopped", "detaching"],
-                    "description": "",
-                    "create": false,
-                    "update": false
                 }
             }
         },
@@ -934,7 +1009,7 @@
             "extends": "operationalEntity",
             "attributes": {
                 "treatment": {
-                    "type": ["flood", "multi", "anyClosest", "anyBalanced", "linkBalanced"],
+                    "type": ["flood", "multicast", "closest", "balanced", "linkBalanced"],
                     "description": "Forwarding treatment for the address: flood - messages delivered to all subscribers along all available paths (this will cause duplicate deliveries if there are redundant paths); multi - one copy of each message delivered to all subscribers; anyClosest - messages delivered to only the closest subscriber; anyBalanced - messages delivered to one subscriber with load balanced across subscribers; linkBalanced - for link-routing, link attaches balanced across destinations."
                 },
                 "inProcess": {
@@ -1027,25 +1102,6 @@
             }
         },
 
-        "router.waypoint": {
-            "description": "Waypoint that is enabled in this router (i.e. a provisioned waypoint with a connector).",
-            "extends": "operationalEntity",
-            "attributes": {
-                "provisionedId": {
-                    "description": "Reference to the provisioning record that created this waypoint",
-                    "type": "string"
-                },
-                "outboundLink": {
-                    "description": "Reference to the link that is outbound from the waypoint to the remote node",
-                    "type": "string"
-                },
-                "inboundLink": {
-                    "description": "Reference to the link that is inbound to the waypoint from the remote node",
-                    "type": "string"
-                }
-            }
-        },
-
         "connection": {
             "description": "Connections to the router's container.",
             "extends": "operationalEntity",

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/ab2734f9/python/qpid_dispatch_internal/dispatch.py
----------------------------------------------------------------------
diff --git a/python/qpid_dispatch_internal/dispatch.py b/python/qpid_dispatch_internal/dispatch.py
index 49f9a83..3b16193 100644
--- a/python/qpid_dispatch_internal/dispatch.py
+++ b/python/qpid_dispatch_internal/dispatch.py
@@ -65,10 +65,12 @@ class QdDll(ctypes.PyDLL):
         self._prototype(self.qd_connection_manager_delete_listener, None, [self.qd_dispatch_p, ctypes.c_void_p])
         self._prototype(self.qd_connection_manager_delete_connector, None, [self.qd_dispatch_p, ctypes.c_void_p])
 
-        self._prototype(self.qd_dispatch_configure_address, None, [self.qd_dispatch_p, py_object])
+        self._prototype(self.qd_dispatch_configure_fixed_address, None, [self.qd_dispatch_p, py_object])
         self._prototype(self.qd_dispatch_configure_waypoint, None, [self.qd_dispatch_p, py_object])
         self._prototype(self.qd_dispatch_configure_lrp, None, [self.qd_dispatch_p, py_object])
-        self._prototype(self.qd_dispatch_configure_route, None, [self.qd_dispatch_p, py_object])
+        self._prototype(self.qd_dispatch_configure_address, None, [self.qd_dispatch_p, py_object])
+        self._prototype(self.qd_dispatch_configure_link_route, None, [self.qd_dispatch_p, py_object])
+        self._prototype(self.qd_dispatch_configure_auto_link, None, [self.qd_dispatch_p, py_object])
 
         self._prototype(self.qd_dispatch_set_agent, None, [self.qd_dispatch_p, py_object])
 

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/ab2734f9/python/qpid_dispatch_internal/management/agent.py
----------------------------------------------------------------------
diff --git a/python/qpid_dispatch_internal/management/agent.py b/python/qpid_dispatch_internal/management/agent.py
index 26a3b54..a7dc4c5 100644
--- a/python/qpid_dispatch_internal/management/agent.py
+++ b/python/qpid_dispatch_internal/management/agent.py
@@ -244,6 +244,48 @@ class RouterEntity(EntityAdapter):
         self._qd.qd_dispatch_configure_router(self._dispatch, self)
 
 
+class AddressEntity(EntityAdapter):
+    def __init__(self, agent, entity_type, attributes=None):
+        super(AddressEntity, self).__init__(agent, entity_type, attributes, validate=False)
+        # Router is a mix of configuration and operational entity.
+        # The statistics attributes are operational not configured.
+        self._add_implementation(
+            CImplementation(agent.qd, entity_type, self._dispatch))
+
+    def _identifier(self): return self.attributes.get('identity')
+
+    def create(self):
+        self._qd.qd_dispatch_configure_address(self._dispatch, self)
+
+
+class LinkRouteEntity(EntityAdapter):
+    def __init__(self, agent, entity_type, attributes=None):
+        super(LinkRouteEntity, self).__init__(agent, entity_type, attributes, validate=False)
+        # Router is a mix of configuration and operational entity.
+        # The statistics attributes are operational not configured.
+        self._add_implementation(
+            CImplementation(agent.qd, entity_type, self._dispatch))
+
+    def _identifier(self): return self.attributes.get('identity')
+
+    def create(self):
+        self._qd.qd_dispatch_configure_link_route(self._dispatch, self)
+
+
+class AutoLinkEntity(EntityAdapter):
+    def __init__(self, agent, entity_type, attributes=None):
+        super(AutoLinkEntity, self).__init__(agent, entity_type, attributes, validate=False)
+        # Router is a mix of configuration and operational entity.
+        # The statistics attributes are operational not configured.
+        self._add_implementation(
+            CImplementation(agent.qd, entity_type, self._dispatch))
+
+    def _identifier(self): return self.attributes.get('identity')
+
+    def create(self):
+        self._qd.qd_dispatch_configure_auto_link(self._dispatch, self)
+
+
 class LogEntity(EntityAdapter):
 
     def __init__(self, agent, entity_type, attributes=None, validate=True):
@@ -296,7 +338,7 @@ class ConnectorEntity(EntityAdapter):
 
 class FixedAddressEntity(EntityAdapter):
     def create(self):
-        self._qd.qd_dispatch_configure_address(self._dispatch, self)
+        self._qd.qd_dispatch_configure_fixed_address(self._dispatch, self)
 
 
 class WaypointEntity(EntityAdapter):
@@ -308,9 +350,17 @@ class LinkRoutePatternEntity(EntityAdapter):
     def create(self):
         self._qd.qd_dispatch_configure_lrp(self._dispatch, self)
 
-class RouteEntity(EntityAdapter):
+class AddressEntity(EntityAdapter):
+    def create(self):
+        self._qd.qd_dispatch_configure_address(self._dispatch, self)
+
+class LinkRouteEntity(EntityAdapter):
+    def create(self):
+        self._qd.qd_dispatch_configure_link_route(self._dispatch, self)
+
+class AutoLinkEntity(EntityAdapter):
     def create(self):
-        self._qd.qd_dispatch_configure_route(self._dispatch, self)
+        self._qd.qd_dispatch_configure_auto_link(self._dispatch, self)
 
 class ConsoleEntity(EntityAdapter):
     def create(self):

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/ab2734f9/src/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 472090d..9ae6d08 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -66,8 +66,8 @@ set(qpid_dispatch_SOURCES
   router_config.c
   router_core/agent.c
   router_core/agent_address.c
+  router_core/agent_config_address.c
   router_core/agent_link.c
-  router_core/agent_route.c
   router_core/connections.c
   router_core/error.c
   router_core/forwarder.c

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/ab2734f9/src/dispatch.c
----------------------------------------------------------------------
diff --git a/src/dispatch.c b/src/dispatch.c
index ad2d621..d4cdafe 100644
--- a/src/dispatch.c
+++ b/src/dispatch.c
@@ -120,9 +120,9 @@ qd_error_t qd_dispatch_configure_router(qd_dispatch_t *qd, qd_entity_t *entity)
     return qd_error_code();
 }
 
-qd_error_t qd_dispatch_configure_address(qd_dispatch_t *qd, qd_entity_t *entity) {
+qd_error_t qd_dispatch_configure_fixed_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);
+    qd_router_configure_fixed_address(qd->router, entity);
     return qd_error_code();
 }
 
@@ -138,9 +138,21 @@ qd_error_t qd_dispatch_configure_lrp(qd_dispatch_t *qd, qd_entity_t *entity) {
     return qd_error_code();
 }
 
-qd_error_t qd_dispatch_configure_route(qd_dispatch_t *qd, qd_entity_t *entity) {
+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();
+}
+
+qd_error_t qd_dispatch_configure_link_route(qd_dispatch_t *qd, qd_entity_t *entity) {
+    if (!qd->router) return qd_error(QD_ERROR_NOT_FOUND, "No router available");
+    qd_router_configure_link_route(qd->router, entity);
+    return qd_error_code();
+}
+
+qd_error_t qd_dispatch_configure_auto_link(qd_dispatch_t *qd, qd_entity_t *entity) {
     if (!qd->router) return qd_error(QD_ERROR_NOT_FOUND, "No router available");
-    qd_router_configure_route(qd->router, entity);
+    qd_router_configure_auto_link(qd->router, entity);
     return qd_error_code();
 }
 

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/ab2734f9/src/router_config.c
----------------------------------------------------------------------
diff --git a/src/router_config.c b/src/router_config.c
index c08307e..d22f8c1 100644
--- a/src/router_config.c
+++ b/src/router_config.c
@@ -27,7 +27,7 @@
 #include "entity_cache.h"
 #include "schema_enum.h"
 
-qd_error_t qd_router_configure_address(qd_router_t *router, qd_entity_t *entity)
+qd_error_t qd_router_configure_fixed_address(qd_router_t *router, qd_entity_t *entity)
 {
     qd_error_clear();
     int                             phase  = qd_entity_opt_long(entity, "phase", -1); QD_ERROR_RET();
@@ -49,17 +49,17 @@ qd_error_t qd_router_configure_address(qd_router_t *router, qd_entity_t *entity)
     }
 
     //
-    // Convert fanout + bias to treatment
+    // Convert fanout + bias to distribution
     //
-    const char *trt;
+    const char *distrib;
 
     if (fanout == QD_SCHEMA_FIXEDADDRESS_FANOUT_MULTIPLE)
-        trt = "multicast";
+        distrib = "multicast";
     else {
         if (bias == QD_SCHEMA_FIXEDADDRESS_BIAS_CLOSEST)
-            trt = "closest";
+            distrib = "closest";
         else
-            trt = "balanced";
+            distrib = "balanced";
     }
 
     //
@@ -67,11 +67,11 @@ qd_error_t qd_router_configure_address(qd_router_t *router, qd_entity_t *entity)
     //
     qd_composed_field_t *body = qd_compose_subfield(0);
     qd_compose_start_map(body);
-    qd_compose_insert_string(body, "address");
+    qd_compose_insert_string(body, "prefix");
     qd_compose_insert_string(body, prefix);
 
-    qd_compose_insert_string(body, "treatment");
-    qd_compose_insert_string(body, trt);
+    qd_compose_insert_string(body, "distribution");
+    qd_compose_insert_string(body, distrib);
     qd_compose_end_map(body);
 
     int              length = 0;
@@ -89,7 +89,7 @@ qd_error_t qd_router_configure_address(qd_router_t *router, qd_entity_t *entity)
     qd_field_iterator_t *iter = qd_field_iterator_buffer(DEQ_HEAD(buffers), 0, length);
     qd_parsed_field_t   *in_body = qd_parse(iter);
 
-    qdr_manage_create(router->router_core, 0, QD_ROUTER_ROUTE, 0, in_body, 0);
+    qdr_manage_create(router->router_core, 0, QD_ROUTER_CONFIG_ADDRESS, 0, in_body, 0);
 
     free(prefix);
     return qd_error_code();
@@ -139,25 +139,15 @@ qd_error_t qd_router_configure_lrp(qd_router_t *router, qd_entity_t *entity)
     //
     qd_composed_field_t *body = qd_compose_subfield(0);
     qd_compose_start_map(body);
-    qd_compose_insert_string(body, "address");
+    qd_compose_insert_string(body, "prefix");
     qd_compose_insert_string(body, prefix);
 
-    qd_compose_insert_string(body, "path");
-    if      (strcmp("in", direction) == 0)
-        qd_compose_insert_string(body, "sink");
-    else if (strcmp("out", direction) == 0)
-        qd_compose_insert_string(body, "source");
-    else
-        qd_compose_insert_string(body, "waypoint");
-
-    qd_compose_insert_string(body, "treatment");
-    qd_compose_insert_string(body, "linkBalanced");
+    qd_compose_insert_string(body, "dir");
+    qd_compose_insert_string(body, direction);
 
     if (connector) {
-        qd_compose_insert_string(body, "connectors");
-        qd_compose_start_list(body);
+        qd_compose_insert_string(body, "connectionName");
         qd_compose_insert_string(body, connector);
-        qd_compose_end_list(body);
     }
 
     qd_compose_end_map(body);
@@ -177,7 +167,7 @@ qd_error_t qd_router_configure_lrp(qd_router_t *router, qd_entity_t *entity)
     qd_field_iterator_t *iter    = qd_field_iterator_buffer(DEQ_HEAD(buffers), 0, length);
     qd_parsed_field_t   *in_body = qd_parse(iter);
 
-    qdr_manage_create(router->router_core, 0, QD_ROUTER_ROUTE, 0, in_body, 0);
+    qdr_manage_create(router->router_core, 0, QD_ROUTER_CONFIG_LINK_ROUTE, 0, in_body, 0);
 
     free(prefix);
     free(connector);
@@ -186,29 +176,84 @@ qd_error_t qd_router_configure_lrp(qd_router_t *router, qd_entity_t *entity)
 }
 
 
-static void qd_router_insert_items(qd_composed_field_t *body, char *list)
+qd_error_t qd_router_configure_address(qd_router_t *router, qd_entity_t *entity)
 {
-    char *saveptr;
-    char *token;
-    char *delim = ", ";
-
-    token = strtok_r(list, delim, &saveptr);
-    while (token) {
-        qd_compose_insert_string(body, token);
-        token = strtok_r(0, delim, &saveptr);
+    char *name      = qd_entity_opt_string(entity, "name", 0);         QD_ERROR_RET();
+    char *prefix    = qd_entity_get_string(entity, "prefix");          QD_ERROR_RET();
+    char *distrib   = qd_entity_opt_string(entity, "distribution", 0); QD_ERROR_RET();
+    bool  waypoint  = qd_entity_opt_bool(entity, "waypoint", false);   QD_ERROR_RET();
+    long  in_phase  = qd_entity_opt_long(entity, "ingressPhase", -1);  QD_ERROR_RET();
+    long  out_phase = qd_entity_opt_long(entity, "egressPhase", -1);   QD_ERROR_RET();
+
+    //
+    // Formulate this configuration create it through the core management API.
+    //
+    qd_composed_field_t *body = qd_compose_subfield(0);
+    qd_compose_start_map(body);
+
+    if (name) {
+        qd_compose_insert_string(body, "name");
+        qd_compose_insert_string(body, name);
     }
+
+    if (prefix) {
+        qd_compose_insert_string(body, "prefix");
+        qd_compose_insert_string(body, prefix);
+    }
+
+    if (distrib) {
+        qd_compose_insert_string(body, "distribution");
+        qd_compose_insert_string(body, distrib);
+    }
+
+    qd_compose_insert_string(body, "waypoint");
+    qd_compose_insert_bool(body, waypoint);
+
+    if (in_phase >= 0) {
+        qd_compose_insert_string(body, "ingressPhase");
+        qd_compose_insert_int(body, in_phase);
+    }
+
+    if (out_phase >= 0) {
+        qd_compose_insert_string(body, "egressPhase");
+        qd_compose_insert_int(body, out_phase);
+    }
+
+    qd_compose_end_map(body);
+
+    int              length = 0;
+    qd_buffer_list_t buffers;
+
+    qd_compose_take_buffers(body, &buffers);
+    qd_compose_free(body);
+
+    qd_buffer_t *buf = DEQ_HEAD(buffers);
+    while (buf) {
+        length += qd_buffer_size(buf);
+        buf = DEQ_NEXT(buf);
+    }
+
+    qd_field_iterator_t *iter    = qd_field_iterator_buffer(DEQ_HEAD(buffers), 0, length);
+    qd_parsed_field_t   *in_body = qd_parse(iter);
+
+    qdr_manage_create(router->router_core, 0, QD_ROUTER_CONFIG_ADDRESS, 0, in_body, 0);
+
+    free(name);
+    free(prefix);
+    free(distrib);
+
+    return qd_error_code();
 }
 
 
-qd_error_t qd_router_configure_route(qd_router_t *router, qd_entity_t *entity)
+qd_error_t qd_router_configure_link_route(qd_router_t *router, qd_entity_t *entity)
 {
-    char *name          = qd_entity_opt_string(entity, "name", 0);          QD_ERROR_RET();
-    char *address       = qd_entity_opt_string(entity, "address", 0);       QD_ERROR_RET();
-    char *path          = qd_entity_opt_string(entity, "path", 0);          QD_ERROR_RET();
-    char *treatment     = qd_entity_opt_string(entity, "treatment", 0);     QD_ERROR_RET();
-    char *connectors    = qd_entity_opt_string(entity, "connectors", 0);    QD_ERROR_RET();
-    char *containers    = qd_entity_opt_string(entity, "containers", 0);    QD_ERROR_RET();
-    char *route_address = qd_entity_opt_string(entity, "route_address", 0); QD_ERROR_RET();
+    char *name      = qd_entity_opt_string(entity, "name", 0);           QD_ERROR_RET();
+    char *prefix    = qd_entity_get_string(entity, "prefix");            QD_ERROR_RET();
+    char *container = qd_entity_opt_string(entity, "containerId", 0);    QD_ERROR_RET();
+    char *c_name    = qd_entity_opt_string(entity, "connectionName", 0); QD_ERROR_RET();
+    char *distrib   = qd_entity_opt_string(entity, "distribution", 0);   QD_ERROR_RET();
+    char *dir       = qd_entity_opt_string(entity, "dir", 0);            QD_ERROR_RET();
 
     //
     // Formulate this configuration as a route and create it through the core management API.
@@ -221,38 +266,104 @@ qd_error_t qd_router_configure_route(qd_router_t *router, qd_entity_t *entity)
         qd_compose_insert_string(body, name);
     }
 
-    if (address) {
-        qd_compose_insert_string(body, "address");
-        qd_compose_insert_string(body, address);
+    if (prefix) {
+        qd_compose_insert_string(body, "prefix");
+        qd_compose_insert_string(body, prefix);
+    }
+
+    if (container) {
+        qd_compose_insert_string(body, "containerId");
+        qd_compose_insert_string(body, container);
+    }
+
+    if (c_name) {
+        qd_compose_insert_string(body, "connectionName");
+        qd_compose_insert_string(body, c_name);
+    }
+
+    if (distrib) {
+        qd_compose_insert_string(body, "distribution");
+        qd_compose_insert_string(body, distrib);
+    }
+
+    if (dir) {
+        qd_compose_insert_string(body, "dir");
+        qd_compose_insert_string(body, dir);
+    }
+
+    qd_compose_end_map(body);
+
+    int              length = 0;
+    qd_buffer_list_t buffers;
+
+    qd_compose_take_buffers(body, &buffers);
+    qd_compose_free(body);
+
+    qd_buffer_t *buf = DEQ_HEAD(buffers);
+    while (buf) {
+        length += qd_buffer_size(buf);
+        buf = DEQ_NEXT(buf);
+    }
+
+    qd_field_iterator_t *iter    = qd_field_iterator_buffer(DEQ_HEAD(buffers), 0, length);
+    qd_parsed_field_t   *in_body = qd_parse(iter);
+
+    qdr_manage_create(router->router_core, 0, QD_ROUTER_CONFIG_LINK_ROUTE, 0, in_body, 0);
+
+    free(name);
+    free(prefix);
+    free(container);
+    free(c_name);
+    free(distrib);
+    free(dir);
+
+    return qd_error_code();
+}
+
+
+qd_error_t qd_router_configure_auto_link(qd_router_t *router, qd_entity_t *entity)
+{
+    char *name      = qd_entity_opt_string(entity, "name", 0);           QD_ERROR_RET();
+    char *addr      = qd_entity_get_string(entity, "addr");              QD_ERROR_RET();
+    char *dir       = qd_entity_get_string(entity, "dir");               QD_ERROR_RET();
+    long  phase     = qd_entity_opt_long(entity, "phase", -1);           QD_ERROR_RET();
+    char *container = qd_entity_opt_string(entity, "containerId", 0);    QD_ERROR_RET();
+    char *c_name    = qd_entity_opt_string(entity, "connectionName", 0); QD_ERROR_RET();
+
+    //
+    // Formulate this configuration as a route and create it through the core management API.
+    //
+    qd_composed_field_t *body = qd_compose_subfield(0);
+    qd_compose_start_map(body);
+
+    if (name) {
+        qd_compose_insert_string(body, "name");
+        qd_compose_insert_string(body, name);
     }
 
-    if (path) {
-        qd_compose_insert_string(body, "path");
-        qd_compose_insert_string(body, path);
+    if (addr) {
+        qd_compose_insert_string(body, "addr");
+        qd_compose_insert_string(body, addr);
     }
 
-    if (treatment) {
-        qd_compose_insert_string(body, "treatment");
-        qd_compose_insert_string(body, treatment);
+    if (dir) {
+        qd_compose_insert_string(body, "dir");
+        qd_compose_insert_string(body, dir);
     }
 
-    if (connectors) {
-        qd_compose_insert_string(body, "connectors");
-        qd_compose_start_list(body);
-        qd_router_insert_items(body, connectors);
-        qd_compose_end_list(body);
+    if (phase >= 0) {
+        qd_compose_insert_string(body, "phase");
+        qd_compose_insert_int(body, phase);
     }
 
-    if (containers) {
-        qd_compose_insert_string(body, "containers");
-        qd_compose_start_list(body);
-        qd_router_insert_items(body, containers);
-        qd_compose_end_list(body);
+    if (container) {
+        qd_compose_insert_string(body, "containerId");
+        qd_compose_insert_string(body, container);
     }
 
-    if (route_address) {
-        qd_compose_insert_string(body, "routeAddress");
-        qd_compose_insert_string(body, route_address);
+    if (c_name) {
+        qd_compose_insert_string(body, "connectionName");
+        qd_compose_insert_string(body, c_name);
     }
 
     qd_compose_end_map(body);
@@ -272,15 +383,13 @@ qd_error_t qd_router_configure_route(qd_router_t *router, qd_entity_t *entity)
     qd_field_iterator_t *iter    = qd_field_iterator_buffer(DEQ_HEAD(buffers), 0, length);
     qd_parsed_field_t   *in_body = qd_parse(iter);
 
-    qdr_manage_create(router->router_core, 0, QD_ROUTER_ROUTE, 0, in_body, 0);
+    qdr_manage_create(router->router_core, 0, QD_ROUTER_CONFIG_AUTO_LINK, 0, in_body, 0);
 
     free(name);
-    free(address);
-    free(path);
-    free(treatment);
-    free(connectors);
-    free(containers);
-    free(route_address);
+    free(addr);
+    free(dir);
+    free(container);
+    free(c_name);
 
     return qd_error_code();
 }

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/ab2734f9/src/router_core/agent.c
----------------------------------------------------------------------
diff --git a/src/router_core/agent.c b/src/router_core/agent.c
index 1833880..5c20953 100644
--- a/src/router_core/agent.c
+++ b/src/router_core/agent.c
@@ -18,7 +18,7 @@
  */
 
 #include <qpid/dispatch/amqp.h>
-#include "agent_route.h"
+#include "agent_config_address.h"
 #include "agent_address.h"
 #include "agent_link.h"
 #include "router_core_private.h"
@@ -170,26 +170,14 @@ qdr_query_t *qdr_manage_query(qdr_core_t              *core,
     qdr_query_t* query = qdr_query(core, context, type, body);
 
     switch (query->entity_type) {
-    case QD_ROUTER_ROUTE:
-        qdr_agent_set_columns(query, attribute_names, qdr_route_columns, QDR_ROUTE_COLUMN_COUNT);
-        break;
-
-    case QD_ROUTER_CONNECTION:
-        break;
-
-    case QD_ROUTER_LINK:
-        qdr_agent_set_columns(query, attribute_names, qdr_link_columns, QDR_LINK_COLUMN_COUNT);
-        break;
-
-    case QD_ROUTER_ADDRESS:
-        qdr_agent_set_columns(query, attribute_names, qdr_address_columns, QDR_ADDRESS_COLUMN_COUNT);
-        break;
-
-    case QD_ROUTER_EXCHANGE:
-        break;
-
-    case QD_ROUTER_BINDING:
-        break;
+    case QD_ROUTER_CONFIG_ADDRESS:    break;
+    case QD_ROUTER_CONFIG_LINK_ROUTE: break;
+    case QD_ROUTER_CONFIG_AUTO_LINK:  break;
+    case QD_ROUTER_CONNECTION:        break;
+    case QD_ROUTER_LINK:              qdr_agent_set_columns(query, attribute_names, qdr_link_columns, QDR_LINK_COLUMN_COUNT);  break;
+    case QD_ROUTER_ADDRESS:           qdr_agent_set_columns(query, attribute_names, qdr_address_columns, QDR_ADDRESS_COLUMN_COUNT); break;
+    case QD_ROUTER_EXCHANGE:          break;
+    case QD_ROUTER_BINDING:           break;
     }
 
     return query;
@@ -199,12 +187,14 @@ qdr_query_t *qdr_manage_query(qdr_core_t              *core,
 void qdr_query_add_attribute_names(qdr_query_t *query)
 {
     switch (query->entity_type) {
-    case QD_ROUTER_ROUTE: qdr_agent_emit_columns(query, qdr_route_columns, QDR_ROUTE_COLUMN_COUNT); break;
-    case QD_ROUTER_CONNECTION:  break;
-    case QD_ROUTER_LINK:        qdr_agent_emit_columns(query, qdr_link_columns, QDR_LINK_COLUMN_COUNT); break;
-    case QD_ROUTER_ADDRESS:     qdr_agent_emit_columns(query, qdr_address_columns, QDR_ADDRESS_COLUMN_COUNT); break;
-    case QD_ROUTER_EXCHANGE:    break;
-    case QD_ROUTER_BINDING:     break;
+    case QD_ROUTER_CONFIG_ADDRESS:    break;
+    case QD_ROUTER_CONFIG_LINK_ROUTE: break;
+    case QD_ROUTER_CONFIG_AUTO_LINK:  break;
+    case QD_ROUTER_CONNECTION:        break;
+    case QD_ROUTER_LINK:              qdr_agent_emit_columns(query, qdr_link_columns, QDR_LINK_COLUMN_COUNT); break;
+    case QD_ROUTER_ADDRESS:           qdr_agent_emit_columns(query, qdr_address_columns, QDR_ADDRESS_COLUMN_COUNT); break;
+    case QD_ROUTER_EXCHANGE:          break;
+    case QD_ROUTER_BINDING:           break;
     }
 }
 
@@ -322,12 +312,14 @@ static void qdr_manage_read_CT(qdr_core_t *core, qdr_action_t *action, bool disc
     qdr_query_t             *query      = action->args.agent.query;
 
     switch (query->entity_type) {
-    case QD_ROUTER_ROUTE:       break;
-    case QD_ROUTER_CONNECTION:  break;
-    case QD_ROUTER_LINK:        break;
-    case QD_ROUTER_ADDRESS:     qdra_address_get_CT(core, name, identity, query, qdr_address_columns); break;
-    case QD_ROUTER_EXCHANGE:    break;
-    case QD_ROUTER_BINDING:     break;
+    case QD_ROUTER_CONFIG_ADDRESS:    break;
+    case QD_ROUTER_CONFIG_LINK_ROUTE: break;
+    case QD_ROUTER_CONFIG_AUTO_LINK:  break;
+    case QD_ROUTER_CONNECTION:        break;
+    case QD_ROUTER_LINK:              break;
+    case QD_ROUTER_ADDRESS:           qdra_address_get_CT(core, name, identity, query, qdr_address_columns); break;
+    case QD_ROUTER_EXCHANGE:          break;
+    case QD_ROUTER_BINDING:           break;
    }
 }
 
@@ -339,13 +331,14 @@ static void qdr_manage_create_CT(qdr_core_t *core, qdr_action_t *action, bool di
     qd_parsed_field_t       *in_body    = action->args.agent.in_body;
 
     switch (query->entity_type) {
-
-    case QD_ROUTER_ROUTE:       qdra_route_create_CT(core, name, query, in_body); break;
-    case QD_ROUTER_CONNECTION:  break;
-    case QD_ROUTER_LINK:        break;
-    case QD_ROUTER_ADDRESS:     break;
-    case QD_ROUTER_EXCHANGE:    break;
-    case QD_ROUTER_BINDING:     break;
+    case QD_ROUTER_CONFIG_ADDRESS:    qdra_config_address_create_CT(core, name, query, in_body); break;
+    case QD_ROUTER_CONFIG_LINK_ROUTE: break;
+    case QD_ROUTER_CONFIG_AUTO_LINK:  break;
+    case QD_ROUTER_CONNECTION:        break;
+    case QD_ROUTER_LINK:              break;
+    case QD_ROUTER_ADDRESS:           break;
+    case QD_ROUTER_EXCHANGE:          break;
+    case QD_ROUTER_BINDING:           break;
 
    }
 
@@ -360,12 +353,14 @@ static void qdr_manage_delete_CT(qdr_core_t *core, qdr_action_t *action, bool di
     qdr_query_t             *query      = action->args.agent.query;
 
     switch (query->entity_type) {
-    case QD_ROUTER_ROUTE:       qdra_route_delete_CT(core, query, name, identity); break;
-    case QD_ROUTER_CONNECTION:  break;
-    case QD_ROUTER_LINK:        break;
-    case QD_ROUTER_ADDRESS:     break;
-    case QD_ROUTER_EXCHANGE:    break;
-    case QD_ROUTER_BINDING:     break;
+    case QD_ROUTER_CONFIG_ADDRESS:    qdra_config_address_delete_CT(core, query, name, identity); break;
+    case QD_ROUTER_CONFIG_LINK_ROUTE: break;
+    case QD_ROUTER_CONFIG_AUTO_LINK:  break;
+    case QD_ROUTER_CONNECTION:        break;
+    case QD_ROUTER_LINK:              break;
+    case QD_ROUTER_ADDRESS:           break;
+    case QD_ROUTER_EXCHANGE:          break;
+    case QD_ROUTER_BINDING:           break;
    }
 }
 
@@ -379,12 +374,14 @@ static void qdrh_query_get_first_CT(qdr_core_t *core, qdr_action_t *action, bool
 
     if (!discard) {
         switch (query->entity_type) {
-        case QD_ROUTER_ROUTE:       qdra_route_get_first_CT(core, query, offset); break;
-        case QD_ROUTER_CONNECTION:  break;
-        case QD_ROUTER_LINK:        qdra_link_get_first_CT(core, query, offset); break;
-        case QD_ROUTER_ADDRESS:     qdra_address_get_first_CT(core, query, offset); break;
-        case QD_ROUTER_EXCHANGE:    break;
-        case QD_ROUTER_BINDING:     break;
+        case QD_ROUTER_CONFIG_ADDRESS:    qdra_config_address_get_first_CT(core, query, offset); break;
+        case QD_ROUTER_CONFIG_LINK_ROUTE: break;
+        case QD_ROUTER_CONFIG_AUTO_LINK:  break;
+        case QD_ROUTER_CONNECTION:        break;
+        case QD_ROUTER_LINK:              qdra_link_get_first_CT(core, query, offset); break;
+        case QD_ROUTER_ADDRESS:           qdra_address_get_first_CT(core, query, offset); break;
+        case QD_ROUTER_EXCHANGE:          break;
+        case QD_ROUTER_BINDING:           break;
         }
     }
 }
@@ -396,12 +393,14 @@ static void qdrh_query_get_next_CT(qdr_core_t *core, qdr_action_t *action, bool
 
     if (!discard) {
         switch (query->entity_type) {
-        case QD_ROUTER_ROUTE:       qdra_route_get_next_CT(core, query); break;
-        case QD_ROUTER_CONNECTION:  break;
-        case QD_ROUTER_LINK:        qdra_link_get_next_CT(core, query); break;
-        case QD_ROUTER_ADDRESS:     qdra_address_get_next_CT(core, query); break;
-        case QD_ROUTER_EXCHANGE:    break;
-        case QD_ROUTER_BINDING:     break;
+        case QD_ROUTER_CONFIG_ADDRESS:    qdra_config_address_get_next_CT(core, query); break;
+        case QD_ROUTER_CONFIG_LINK_ROUTE: break;
+        case QD_ROUTER_CONFIG_AUTO_LINK:  break;
+        case QD_ROUTER_CONNECTION:        break;
+        case QD_ROUTER_LINK:              qdra_link_get_next_CT(core, query); break;
+        case QD_ROUTER_ADDRESS:           qdra_address_get_next_CT(core, query); break;
+        case QD_ROUTER_EXCHANGE:          break;
+        case QD_ROUTER_BINDING:           break;
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/ab2734f9/src/router_core/agent_config_address.c
----------------------------------------------------------------------
diff --git a/src/router_core/agent_config_address.c b/src/router_core/agent_config_address.c
new file mode 100644
index 0000000..2a86ad8
--- /dev/null
+++ b/src/router_core/agent_config_address.c
@@ -0,0 +1,415 @@
+/*
+ * 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/ctools.h>
+#include "agent_config_address.h"
+#include <stdio.h>
+
+#define QDR_CONFIG_ADDRESS_NAME          0
+#define QDR_CONFIG_ADDRESS_IDENTITY      1
+#define QDR_CONFIG_ADDRESS_TYPE          2
+#define QDR_CONFIG_ADDRESS_PREFIX        3
+#define QDR_CONFIG_ADDRESS_DISTRIBUTION  4
+#define QDR_CONFIG_ADDRESS_WAYPOINT      5
+#define QDR_CONFIG_ADDRESS_IN_PHASE      6
+#define QDR_CONFIG_ADDRESS_OUT_PHASE     7
+
+const char *qdr_config_address_columns[] =
+    {"name",
+     "identity",
+     "type",
+     "prefix",
+     "distribution",
+     "waypoint",
+     "ingressPhase",
+     "egressPhase",
+     0};
+
+
+static void qdr_config_address_insert_column_CT(qdr_address_config_t *addr, int col, qd_composed_field_t *body, bool as_map)
+{
+    const char *text = 0;
+    const char *key;
+
+    if (as_map)
+        qd_compose_insert_string(body, qdr_config_address_columns[col]);
+
+    switch(col) {
+    case QDR_CONFIG_ADDRESS_NAME:
+        if (addr->name)
+            qd_compose_insert_string(body, addr->name);
+        else
+            qd_compose_insert_null(body);
+        break;
+
+    case QDR_CONFIG_ADDRESS_IDENTITY: {
+        char id_str[100];
+        snprintf(id_str, 100, "%ld", addr->identity);
+        qd_compose_insert_string(body, id_str);
+        break;
+    }
+
+    case QDR_CONFIG_ADDRESS_TYPE:
+        qd_compose_insert_string(body, "org.apache.qpid.dispatch.config.address");
+        break;
+
+    case QDR_CONFIG_ADDRESS_PREFIX:
+        key = (const char*) qd_hash_key_by_handle(addr->hash_handle);
+        if (key && key[0] == 'Z')
+            qd_compose_insert_string(body, &key[1]);
+        else
+            qd_compose_insert_null(body);
+        break;
+
+    case QDR_CONFIG_ADDRESS_DISTRIBUTION:
+        switch (addr->treatment) {
+        case QD_TREATMENT_MULTICAST_FLOOD:
+        case QD_TREATMENT_MULTICAST_ONCE:   text = "multicast"; break;
+        case QD_TREATMENT_ANYCAST_CLOSEST:  text = "closest";   break;
+        case QD_TREATMENT_ANYCAST_BALANCED: text = "balanced";  break;
+        default:
+            text = 0;
+        }
+
+        if (text)
+            qd_compose_insert_string(body, text);
+        else
+            qd_compose_insert_null(body);
+
+        break;
+
+    case QDR_CONFIG_ADDRESS_WAYPOINT:
+        qd_compose_insert_bool(body, addr->in_phase == 0 && addr->out_phase == 1);
+        break;
+
+    case QDR_CONFIG_ADDRESS_IN_PHASE:
+        qd_compose_insert_int(body, addr->in_phase);
+        break;
+
+    case QDR_CONFIG_ADDRESS_OUT_PHASE:
+        qd_compose_insert_int(body, addr->out_phase);
+        break;
+    }
+}
+
+
+static void qdr_agent_write_config_address_CT(qdr_query_t *query,  qdr_address_config_t *addr)
+{
+    qd_composed_field_t *body = query->body;
+
+    qd_compose_start_list(body);
+    int i = 0;
+    while (query->columns[i] >= 0) {
+        qdr_config_address_insert_column_CT(addr, query->columns[i], body, false);
+        i++;
+    }
+    qd_compose_end_list(body);
+}
+
+
+static void qdr_manage_advance_config_address_CT(qdr_query_t *query, qdr_address_config_t *addr)
+{
+    query->next_offset++;
+    addr = DEQ_NEXT(addr);
+    query->more = !!addr;
+}
+
+
+void qdra_config_address_get_first_CT(qdr_core_t *core, qdr_query_t *query, int offset)
+{
+    //
+    // Queries that get this far will always succeed.
+    //
+    query->status = QD_AMQP_OK;
+
+    //
+    // If the offset goes beyond the set of objects, end the query now.
+    //
+    if (offset >= DEQ_SIZE(core->addr_config)) {
+        query->more = false;
+        qdr_agent_enqueue_response_CT(core, query);
+        return;
+    }
+
+    //
+    // Run to the object at the offset.
+    //
+    qdr_address_config_t *addr = DEQ_HEAD(core->addr_config);
+    for (int i = 0; i < offset && addr; i++)
+        addr = DEQ_NEXT(addr);
+    assert(addr);
+
+    //
+    // Write the columns of the object into the response body.
+    //
+    qdr_agent_write_config_address_CT(query, addr);
+
+    //
+    // Advance to the next address
+    //
+    query->next_offset = offset;
+    qdr_manage_advance_config_address_CT(query, addr);
+
+    //
+    // Enqueue the response.
+    //
+    qdr_agent_enqueue_response_CT(core, query);
+}
+
+
+void qdra_config_address_get_next_CT(qdr_core_t *core, qdr_query_t *query)
+{
+    qdr_address_config_t *addr = 0;
+
+    if (query->next_offset < DEQ_SIZE(core->addr_config)) {
+        addr = DEQ_HEAD(core->addr_config);
+        for (int i = 0; i < query->next_offset && addr; i++)
+            addr = DEQ_NEXT(addr);
+    }
+
+    if (addr) {
+        //
+        // Write the columns of the addr entity into the response body.
+        //
+        qdr_agent_write_config_address_CT(query, addr);
+
+        //
+        // Advance to the next object
+        //
+        qdr_manage_advance_config_address_CT(query, addr);
+    } else
+        query->more = false;
+
+    //
+    // Enqueue the response.
+    //
+    qdr_agent_enqueue_response_CT(core, query);
+}
+
+
+static qd_address_treatment_t qdra_address_treatment_CT(qd_parsed_field_t *field)
+{
+    if (field) {
+        qd_field_iterator_t *iter = qd_parse_raw(field);
+        if (qd_field_iterator_equal(iter, (unsigned char*) "multicast"))    return QD_TREATMENT_MULTICAST_ONCE;
+        if (qd_field_iterator_equal(iter, (unsigned char*) "closest"))      return QD_TREATMENT_ANYCAST_CLOSEST;
+        if (qd_field_iterator_equal(iter, (unsigned char*) "balanced"))     return QD_TREATMENT_ANYCAST_BALANCED;
+    }
+    return QD_TREATMENT_ANYCAST_BALANCED;
+}
+
+
+static qdr_address_config_t *qdr_address_config_find_by_identity_CT(qdr_core_t *core, qd_field_iterator_t *identity)
+{
+    if (!identity)
+        return 0;
+
+    qdr_address_config_t *rc = DEQ_HEAD(core->addr_config);
+    while (rc) {
+        // Convert the passed in identity to a char*
+        char id[100];
+        snprintf(id, 100, "%ld", rc->identity);
+        if (qd_field_iterator_equal(identity, (const unsigned char*) id))
+            break;
+        rc = DEQ_NEXT(rc);
+    }
+
+    return rc;
+
+}
+
+
+static qdr_address_config_t *qdr_address_config_find_by_name_CT(qdr_core_t *core, qd_field_iterator_t *name)
+{
+    if (!name)
+        return 0;
+
+    qdr_address_config_t *rc = DEQ_HEAD(core->addr_config);
+    while (rc) { // Sometimes the name can be null
+        if (rc->name && qd_field_iterator_equal(name, (const unsigned char*) rc->name))
+            break;
+        rc = DEQ_NEXT(rc);
+    }
+
+    return rc;
+}
+
+
+void qdra_config_address_delete_CT(qdr_core_t          *core,
+                                   qdr_query_t         *query,
+                                   qd_field_iterator_t *name,
+                                   qd_field_iterator_t *identity)
+{
+    qdr_address_config_t *addr = 0;
+
+    if (!name && !identity)
+        query->status = QD_AMQP_BAD_REQUEST;
+    else {
+        if (identity)
+            addr = qdr_address_config_find_by_identity_CT(core, identity);
+        else if (name)
+            addr = qdr_address_config_find_by_name_CT(core, name);
+
+        if (addr) {
+            //
+            // Remove the address from the list and the hash index.
+            //
+            qd_hash_remove_by_handle(core->addr_hash, addr->hash_handle);
+            DEQ_REMOVE(core->addr_config, addr);
+
+            //
+            // Free resources associated with this address.
+            //
+            if (addr->name)
+                free(addr->name);
+            free_qdr_address_config_t(addr);
+
+            query->status = QD_AMQP_NO_CONTENT;
+        } else
+            query->status = QD_AMQP_NOT_FOUND;
+    }
+
+    //
+    // Enqueue the response.
+    //
+    qdr_agent_enqueue_response_CT(core, query);
+}
+
+void qdra_config_address_create_CT(qdr_core_t          *core,
+                                   qd_field_iterator_t *name,
+                                   qdr_query_t         *query,
+                                   qd_parsed_field_t   *in_body)
+{
+    while (true) {
+        //
+        // Ensure there isn't a duplicate name and that the body is a map
+        //
+        qdr_address_config_t *addr = DEQ_HEAD(core->addr_config);
+        while (addr) {
+            if (name && addr->name && qd_field_iterator_equal(name, (const unsigned char*) addr->name))
+                break;
+            addr = DEQ_NEXT(addr);
+        }
+
+        if (!!addr) {
+            query->status = QD_AMQP_BAD_REQUEST;
+            query->status.description = "Name conflicts with an existing entity";
+            break;
+        }
+
+        if (!qd_parse_is_map(in_body)) {
+            query->status = QD_AMQP_BAD_REQUEST;
+            break;
+        }
+
+        //
+        // Extract the fields from the request
+        //
+        qd_parsed_field_t *prefix_field    = qd_parse_value_by_key(in_body, qdr_config_address_columns[QDR_CONFIG_ADDRESS_PREFIX]);
+        qd_parsed_field_t *distrib_field   = qd_parse_value_by_key(in_body, qdr_config_address_columns[QDR_CONFIG_ADDRESS_DISTRIBUTION]);
+        qd_parsed_field_t *waypoint_field  = qd_parse_value_by_key(in_body, qdr_config_address_columns[QDR_CONFIG_ADDRESS_WAYPOINT]);
+        qd_parsed_field_t *in_phase_field  = qd_parse_value_by_key(in_body, qdr_config_address_columns[QDR_CONFIG_ADDRESS_IN_PHASE]);
+        qd_parsed_field_t *out_phase_field = qd_parse_value_by_key(in_body, qdr_config_address_columns[QDR_CONFIG_ADDRESS_OUT_PHASE]);
+
+        //
+        // Prefix field is mandatory.  Fail if it is not here.
+        //
+        if (!prefix_field) {
+            query->status = QD_AMQP_BAD_REQUEST;
+            break;
+        }
+
+        //
+        // Ensure that there isn't another configured address with the same prefix
+        //
+        qd_field_iterator_t *iter = qd_parse_raw(prefix_field);
+        qd_address_iterator_reset_view(iter, ITER_VIEW_ADDRESS_HASH);
+        qd_address_iterator_override_prefix(iter, 'Z');
+        addr = 0;
+        qd_hash_retrieve(core->addr_hash, iter, (void**) &addr);
+        if (!!addr) {
+            query->status = QD_AMQP_BAD_REQUEST;
+            query->status.description = "Address prefix conflicts with an existing entity";
+            break;
+        }
+
+        bool waypoint  = waypoint_field  ? qd_parse_as_bool(waypoint_field) : false;
+        int  in_phase  = in_phase_field  ? qd_parse_as_int(in_phase_field)  : -1;
+        int  out_phase = out_phase_field ? qd_parse_as_int(in_phase_field)  : -1;
+
+        //
+        // Handle the address-phasing logic.  If the phases are provided, use them.  Otherwise
+        // use the waypoint flag to set the most common defaults.
+        //
+        if (in_phase == -1 && out_phase == -1) {
+            in_phase  = 0;
+            out_phase = waypoint ? 1 : 0;
+        }
+
+        //
+        // Validate the phase values
+        //
+        if (in_phase < 0 || in_phase > 9 || out_phase < 0 || out_phase > 9) {
+            query->status = QD_AMQP_BAD_REQUEST;
+            query->status.description = "Phase values must be between 0 and 9";
+            break;
+        }
+
+        //
+        // The request is good.  Create the entity and insert it into the hash index and list.
+        //
+        addr = new_qdr_address_config_t();
+        DEQ_ITEM_INIT(addr);
+        addr->name      = name ? (char*) qd_field_iterator_copy(name) : 0;
+        addr->identity  = qdr_identifier(core);
+        addr->treatment = qdra_address_treatment_CT(distrib_field);
+        addr->in_phase  = in_phase;
+        addr->out_phase = out_phase;
+
+        qd_hash_insert(core->addr_hash, iter, addr, &addr->hash_handle);
+        DEQ_INSERT_TAIL(core->addr_config, addr);
+
+        //
+        // Compose the result map for the response.
+        //
+        if (query->body) {
+            qd_compose_start_map(query->body);
+            for (int col = 0; col < QDR_CONFIG_ADDRESS_COLUMN_COUNT; col++)
+                qdr_config_address_insert_column_CT(addr, col, query->body, true);
+            qd_compose_end_map(query->body);
+        }
+
+        query->status = QD_AMQP_CREATED;
+        break;
+    }
+
+    //
+    // Enqueue the response if there is a body. If there is no body, this is a management
+    // operation created internally by the configuration file parser.
+    //
+    if (query->body) {
+        //
+        // If there was an error in processing the create, insert a NULL value into the body.
+        //
+        if (query->status.status / 100 > 2)
+            qd_compose_insert_null(query->body);
+        qdr_agent_enqueue_response_CT(core, query);
+    } else
+        free_qdr_query_t(query);
+}

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/ab2734f9/src/router_core/agent_config_address.h
----------------------------------------------------------------------
diff --git a/src/router_core/agent_config_address.h b/src/router_core/agent_config_address.h
new file mode 100644
index 0000000..97d863b
--- /dev/null
+++ b/src/router_core/agent_config_address.h
@@ -0,0 +1,35 @@
+#ifndef qdr_agent_config_address
+#define qdr_agent_config_address 1
+/*
+ * 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 "router_core_private.h"
+
+void qdra_config_address_get_first_CT(qdr_core_t *core, qdr_query_t *query, int offset);
+void qdra_config_address_get_next_CT(qdr_core_t *core, qdr_query_t *query);
+void qdra_config_address_create_CT(qdr_core_t *core, qd_field_iterator_t *name, qdr_query_t *query, qd_parsed_field_t *in_body);
+void qdra_config_address_update_CT(qdr_core_t *core, qdr_query_t *query, qd_parsed_field_t *in_body);
+void qdra_config_address_delete_CT(qdr_core_t *core, qdr_query_t *query, qd_field_iterator_t *name,
+                                qd_field_iterator_t *identity);
+
+#define QDR_CONFIG_ADDRESS_COLUMN_COUNT 8
+
+const char *qdr_config_address_columns[QDR_CONFIG_ADDRESS_COLUMN_COUNT + 1];
+
+#endif

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/ab2734f9/src/router_core/agent_route.c
----------------------------------------------------------------------
diff --git a/src/router_core/agent_route.c b/src/router_core/agent_route.c
deleted file mode 100644
index 383d1bc..0000000
--- a/src/router_core/agent_route.c
+++ /dev/null
@@ -1,421 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#include <qpid/dispatch/ctools.h>
-#include "agent_route.h"
-#include "route_control.h"
-#include <stdio.h>
-
-#define QDR_ROUTE_NAME          0
-#define QDR_ROUTE_IDENTITY      1
-#define QDR_ROUTE_TYPE          2
-#define QDR_ROUTE_ADDRESS       3
-#define QDR_ROUTE_PATH          4
-#define QDR_ROUTE_TREATMENT     5
-#define QDR_ROUTE_CONNECTORS    6
-#define QDR_ROUTE_CONTAINERS    7
-#define QDR_ROUTE_ROUTE_ADDRESS 8
-
-const char *qdr_route_columns[] =
-    {"name",
-     "identity",
-     "type",
-     "address",
-     "path",
-     "treatment",
-     "connectors",
-     "containers",
-     "routeAddress",
-     0};
-
-
-static void qdr_route_insert_column_CT(qdr_route_config_t *route, int col, qd_composed_field_t *body, bool as_map)
-{
-    const char *text = 0;
-    qdr_route_active_t *active;
-    const char         *key;
-
-    if (as_map)
-        qd_compose_insert_string(body, qdr_route_columns[col]);
-
-    switch(col) {
-    case QDR_ROUTE_NAME:
-        if (route->name)
-            qd_compose_insert_string(body, route->name);
-        else
-            qd_compose_insert_null(body);
-        break;
-
-    case QDR_ROUTE_IDENTITY: {
-        char id_str[100];
-        snprintf(id_str, 100, "%ld", route->identity);
-        qd_compose_insert_string(body, id_str);
-        break;
-    }
-
-    case QDR_ROUTE_TYPE:
-        qd_compose_insert_string(body, "org.apache.qpid.dispatch.route");
-        break;
-
-    case QDR_ROUTE_ADDRESS:
-        if (route->addr_config)
-            qd_compose_insert_string(body, (const char*) qd_hash_key_by_handle(route->addr_config->hash_handle));
-        else
-            qd_compose_insert_null(body);
-        break;
-
-    case QDR_ROUTE_PATH:
-        switch (route->path) {
-        case QDR_ROUTE_PATH_DIRECT:   text = "direct";  break;
-        case QDR_ROUTE_PATH_SOURCE:   text = "source";  break;
-        case QDR_ROUTE_PATH_SINK:     text = "sink";    break;
-        case QDR_ROUTE_PATH_WAYPOINT: text = "waypoint"; break;
-        }
-        qd_compose_insert_string(body, text);
-        break;
-
-    case QDR_ROUTE_TREATMENT:
-        switch (route->treatment) {
-        case QD_TREATMENT_MULTICAST_FLOOD:
-        case QD_TREATMENT_MULTICAST_ONCE:   text = "multicast";    break;
-        case QD_TREATMENT_ANYCAST_CLOSEST:  text = "closest";      break;
-        case QD_TREATMENT_ANYCAST_BALANCED: text = "balanced";     break;
-        case QD_TREATMENT_LINK_BALANCED:    text = "linkBalanced"; break;
-        }
-        qd_compose_insert_string(body, text);
-        break;
-
-    case QDR_ROUTE_CONNECTORS:
-        qd_compose_start_list(body);
-        active = DEQ_HEAD(route->active_list);
-        while(active) {
-            key = (const char*) qd_hash_key_by_handle(active->conn_id->hash_handle);
-            if (key && key[0] == 'L')
-                qd_compose_insert_string(body, &key[1]);
-            active = DEQ_NEXT(active);
-        }
-        qd_compose_end_list(body);
-        break;
-
-    case QDR_ROUTE_CONTAINERS:
-        qd_compose_start_list(body);
-        active = DEQ_HEAD(route->active_list);
-        while(active) {
-            key = (const char*) qd_hash_key_by_handle(active->conn_id->hash_handle);
-            if (key && key[0] == 'C')
-                qd_compose_insert_string(body, &key[1]);
-            active = DEQ_NEXT(active);
-        }
-        qd_compose_end_list(body);
-        break;
-
-    case QDR_ROUTE_ROUTE_ADDRESS:
-        qd_compose_insert_null(body);
-        break;
-    }
-}
-
-
-static void qdr_agent_write_route_CT(qdr_query_t *query,  qdr_route_config_t *route)
-{
-    qd_composed_field_t *body = query->body;
-
-    qd_compose_start_list(body);
-    int i = 0;
-    while (query->columns[i] >= 0) {
-        qdr_route_insert_column_CT(route, query->columns[i], body, false);
-        i++;
-    }
-    qd_compose_end_list(body);
-}
-
-static void qdr_manage_advance_route_CT(qdr_query_t *query, qdr_route_config_t *route)
-{
-    query->next_offset++;
-    route = DEQ_NEXT(route);
-    query->more = !!route;
-}
-
-
-void qdra_route_get_first_CT(qdr_core_t *core, qdr_query_t *query, int offset)
-{
-    //
-    // Queries that get this far will always succeed.
-    //
-    query->status = QD_AMQP_OK;
-
-    //
-    // If the offset goes beyond the set of objects, end the query now.
-    //
-    if (offset >= DEQ_SIZE(core->route_config)) {
-        query->more = false;
-        qdr_agent_enqueue_response_CT(core, query);
-        return;
-    }
-
-    //
-    // Run to the object at the offset.
-    //
-    qdr_route_config_t *route = DEQ_HEAD(core->route_config);
-    for (int i = 0; i < offset && route; i++)
-        route = DEQ_NEXT(route);
-    assert(route);
-
-    //
-    // Write the columns of the object into the response body.
-    //
-    qdr_agent_write_route_CT(query, route);
-
-    //
-    // Advance to the next address
-    //
-    query->next_offset = offset;
-    qdr_manage_advance_route_CT(query, route);
-
-    //
-    // Enqueue the response.
-    //
-    qdr_agent_enqueue_response_CT(core, query);
-}
-
-
-void qdra_route_get_next_CT(qdr_core_t *core, qdr_query_t *query)
-{
-    qdr_route_config_t *route = 0;
-
-    if (query->next_offset < DEQ_SIZE(core->route_config)) {
-        route = DEQ_HEAD(core->route_config);
-        for (int i = 0; i < query->next_offset && route; i++)
-            route = DEQ_NEXT(route);
-    }
-
-    if (route) {
-        //
-        // Write the columns of the route entity into the response body.
-        //
-        qdr_agent_write_route_CT(query, route);
-
-        //
-        // Advance to the next object
-        //
-        qdr_manage_advance_route_CT(query, route);
-    } else
-        query->more = false;
-
-    //
-    // Enqueue the response.
-    //
-    qdr_agent_enqueue_response_CT(core, query);
-}
-
-
-static qd_address_treatment_t qdra_treatment(qd_parsed_field_t *field)
-{
-    if (field) {
-        qd_field_iterator_t *iter = qd_parse_raw(field);
-        if (qd_field_iterator_equal(iter, (unsigned char*) "multicast"))    return QD_TREATMENT_MULTICAST_ONCE;
-        if (qd_field_iterator_equal(iter, (unsigned char*) "closest"))      return QD_TREATMENT_ANYCAST_CLOSEST;
-        if (qd_field_iterator_equal(iter, (unsigned char*) "balanced"))     return QD_TREATMENT_ANYCAST_BALANCED;
-        if (qd_field_iterator_equal(iter, (unsigned char*) "linkBalanced")) return QD_TREATMENT_LINK_BALANCED;
-    }
-    return QD_TREATMENT_ANYCAST_BALANCED;
-}
-
-static qdr_route_config_t *qdr_route_config_find_by_identity(qdr_core_t *core, qd_field_iterator_t *identity) {
-    if (!identity)
-        return 0;
-
-    qdr_route_config_list_t  route_config = core->route_config;
-
-    qdr_route_config_t *rc = DEQ_HEAD(route_config);
-
-    while (rc) {
-        // Convert the passed in identity to a char*
-        char id[100];
-        snprintf(id, 100, "%ld", rc->identity);
-        if (qd_field_iterator_equal(identity, (const unsigned char *)id))
-            break;
-        rc = DEQ_NEXT(rc);
-    }
-
-    return rc;
-
-}
-
-static qdr_route_config_t *qdr_route_config_find_by_name(qdr_core_t *core, qd_field_iterator_t *name) {
-    if (!name)
-        return 0;
-
-    qdr_route_config_list_t  route_config = core->route_config;
-
-    qdr_route_config_t *rc = DEQ_HEAD(route_config);
-
-    while (rc) {// Sometimes the name can be null
-        if (rc->name && qd_field_iterator_equal(name, (const unsigned char *)rc->name))
-            break;
-        rc = DEQ_NEXT(rc);
-    }
-
-    return rc;
-
-}
-
-static void qdra_route_delete_route_set_status(qdr_core_t *core, qdr_query_t *query, qdr_route_config_t *route)
-{
-    if (route) {
-        qdr_route_delete_CT(core, route);
-        query->status = QD_AMQP_NO_CONTENT;
-    }
-    else {
-        query->status = QD_AMQP_NOT_FOUND;
-    }
-}
-
-void qdra_route_delete_CT(qdr_core_t          *core,
-                          qdr_query_t          *query,
-                          qd_field_iterator_t *name,
-                          qd_field_iterator_t *identity)
-{
-    if (identity) {
-         qdr_route_config_t *route = qdr_route_config_find_by_identity(core, identity);
-         qdra_route_delete_route_set_status(core, query, route);
-    }
-    else if (name) {
-        qdr_route_config_t *route = qdr_route_config_find_by_name(core, name);
-        qdra_route_delete_route_set_status(core, query, route);
-    }
-    else { // No name and no identity
-        query->status = QD_AMQP_BAD_REQUEST;
-    }
-
-    //
-    // Enqueue the response.
-    //
-    qdr_agent_enqueue_response_CT(core, query);
-}
-
-void qdra_route_create_CT(qdr_core_t *core, qd_field_iterator_t *name,
-                          qdr_query_t *query, qd_parsed_field_t *in_body)
-{
-    // TODO - Validation
-    //    - No duplicate names
-    //    - For "direct" path, no containers or connections
-    //    - For "direct" path, no link-* treatments
-
-    while (true) {
-        //
-        // Validation of the request occurs here.  Make sure the body is a map.
-        //
-        if (!qd_parse_is_map(in_body)) {
-            query->status = QD_AMQP_BAD_REQUEST;
-            break;
-        }
-
-        //
-        // Extract the fields from the request
-        //
-        qd_parsed_field_t *addr_field       = qd_parse_value_by_key(in_body, qdr_route_columns[QDR_ROUTE_ADDRESS]);
-        qd_parsed_field_t *path_field       = qd_parse_value_by_key(in_body, qdr_route_columns[QDR_ROUTE_PATH]);
-        qd_parsed_field_t *conn_field       = qd_parse_value_by_key(in_body, qdr_route_columns[QDR_ROUTE_CONNECTORS]);
-        qd_parsed_field_t *cont_field       = qd_parse_value_by_key(in_body, qdr_route_columns[QDR_ROUTE_CONTAINERS]);
-        qd_parsed_field_t *treatment_field  = qd_parse_value_by_key(in_body, qdr_route_columns[QDR_ROUTE_TREATMENT]);
-        qd_parsed_field_t *route_addr_field = qd_parse_value_by_key(in_body, qdr_route_columns[QDR_ROUTE_ROUTE_ADDRESS]);
-
-        //
-        // Determine the path, which defaults to Direct
-        //
-        qdr_route_path_t path = QDR_ROUTE_PATH_DIRECT;
-        if (path_field) {
-            qd_field_iterator_t *path_iter = qd_parse_raw(path_field);
-            if  (qd_field_iterator_equal(path_iter, (unsigned char*) "direct"))
-                path = QDR_ROUTE_PATH_DIRECT;
-            else if (qd_field_iterator_equal(path_iter, (unsigned char*) "source"))
-                path = QDR_ROUTE_PATH_SOURCE;
-            else if (qd_field_iterator_equal(path_iter, (unsigned char*) "sink"))
-                path = QDR_ROUTE_PATH_SINK;
-            else if (qd_field_iterator_equal(path_iter, (unsigned char*) "waypoint"))
-                path = QDR_ROUTE_PATH_WAYPOINT;
-            else {
-                query->status = QD_AMQP_BAD_REQUEST;
-                break;
-            }
-        }
-
-        qd_address_treatment_t treatment = qdra_treatment(treatment_field);
-
-        //
-        // Ask the route_control module to create the route object and put into effect any needed
-        // side effects.
-        //
-        qdr_route_config_t *route;
-        const char *error = qdr_route_create_CT(core, name, path, treatment, addr_field, route_addr_field, &route);
-
-        if (error) {
-            query->status.status      = 400;
-            query->status.description = error;
-            break;
-        }
-
-        //
-        // Add the initial list of connection labels to the route
-        //
-        if (conn_field && qd_parse_is_list(conn_field)) {
-            uint32_t count = qd_parse_sub_count(conn_field);
-            for (uint32_t i = 0; i < count; i++) {
-                qd_parsed_field_t *conn_label = qd_parse_sub_value(conn_field, i);
-                qdr_route_connection_add_CT(core, route, conn_label, false);
-            }
-        }
-
-        //
-        // Add the initial list of container IDs to the route
-        //
-        if (cont_field && qd_parse_is_list(cont_field)) {
-            uint32_t count = qd_parse_sub_count(cont_field);
-            for (uint32_t i = 0; i < count; i++) {
-                qd_parsed_field_t *cont_id = qd_parse_sub_value(cont_field, i);
-                qdr_route_connection_add_CT(core, route, cont_id, true);
-            }
-        }
-
-        //
-        // Compose the result map for the response.
-        //
-        if (query->body) {
-            qd_compose_start_map(query->body);
-            for (int col = 0; col < QDR_ROUTE_COLUMN_COUNT; col++)
-                qdr_route_insert_column_CT(route, col, query->body, true);
-            qd_compose_end_map(query->body);
-        }
-
-        query->status = QD_AMQP_CREATED;
-        break;
-    }
-
-    //
-    // Enqueue the response if there is a body. If there is no body, this is a management
-    // operation created internally by the configuration file parser.
-    //
-    if (query->body) {
-        if (query->status.status / 100 > 2)
-            qd_compose_insert_null(query->body);
-        qdr_agent_enqueue_response_CT(core, query);
-    } else
-        free_qdr_query_t(query);
-}

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/ab2734f9/src/router_core/agent_route.h
----------------------------------------------------------------------
diff --git a/src/router_core/agent_route.h b/src/router_core/agent_route.h
deleted file mode 100644
index ec8d6ba..0000000
--- a/src/router_core/agent_route.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef qdr_agent_route
-#define qdr_agent_route 1
-/*
- * 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 "router_core_private.h"
-
-void qdra_route_get_first_CT(qdr_core_t *core, qdr_query_t *query, int offset);
-void qdra_route_get_next_CT(qdr_core_t *core, qdr_query_t *query);
-void qdra_route_create_CT(qdr_core_t *core, qd_field_iterator_t *name, qdr_query_t *query, qd_parsed_field_t *in_body);
-void qdra_route_update_CT(qdr_core_t *core, qdr_query_t *query, qd_parsed_field_t *in_body);
-void qdra_route_delete_CT(qdr_core_t *core, qdr_query_t *query, qd_field_iterator_t *name,
-                                qd_field_iterator_t *identity);
-
-#define QDR_ROUTE_COLUMN_COUNT 9
-
-const char *qdr_route_columns[QDR_ROUTE_COLUMN_COUNT + 1];
-
-#endif

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/ab2734f9/src/router_core/management_agent.c
----------------------------------------------------------------------
diff --git a/src/router_core/management_agent.c b/src/router_core/management_agent.c
index 82f8c53..6a8e1a3 100644
--- a/src/router_core/management_agent.c
+++ b/src/router_core/management_agent.c
@@ -39,10 +39,11 @@ const char *IDENTITY = "identity";
 const char *OPERATION = "operation";
 const char *ATTRIBUTE_NAMES = "attributeNames";
 
-const unsigned char *route_entity_type = (unsigned char*) "org.apache.qpid.dispatch.route";
-const unsigned char *waypoint_entity_type = (unsigned char*) "org.apache.qpid.dispatch.waypoint";
-const unsigned char *address_entity_type = (unsigned char*) "org.apache.qpid.dispatch.router.address";
-const unsigned char *link_entity_type    = (unsigned char*) "org.apache.qpid.dispatch.router.link";
+const unsigned char *config_address_entity_type = (unsigned char*) "org.apache.qpid.dispatch.router.config.address";
+const unsigned char *link_route_entity_type     = (unsigned char*) "org.apache.qpid.dispatch.router.config.linkRoute";
+const unsigned char *auto_link_entity_type      = (unsigned char*) "org.apache.qpid.dispatch.router.config.autoLink";
+const unsigned char *address_entity_type        = (unsigned char*) "org.apache.qpid.dispatch.router.address";
+const unsigned char *link_entity_type           = (unsigned char*) "org.apache.qpid.dispatch.router.link";
 
 const char * const status_description = "statusDescription";
 const char * const correlation_id = "correlation-id";
@@ -52,14 +53,11 @@ const char * const status_code = "statusCode";
 const char * MANAGEMENT_INTERNAL = "_local/$_management_internal";
 
 //TODO - Move these to amqp.h
-const unsigned char *MANAGEMENT_QUERY                  = (unsigned char*) "QUERY";
-const unsigned char *MANAGEMENT_CREATE                 = (unsigned char*) "CREATE";
-const unsigned char *MANAGEMENT_READ                   = (unsigned char*) "READ";
-const unsigned char *MANAGEMENT_UPDATE                 = (unsigned char*) "UPDATE";
-const unsigned char *MANAGEMENT_DELETE                 = (unsigned char*) "DELETE";
-const unsigned char *MANAGEMENT_ADD_CONTAINER          = (unsigned char*) "ADD-CONTAINER";
-const unsigned char *MANAGEMENT_REMOVE_CONTAINER_CLEAN = (unsigned char*) "REMOVE-CONTAINER-CLEAN";
-const unsigned char *MANAGEMENT_REMOVE_CONTAINER_HARD  = (unsigned char*) "REMOVE-CONTAINER-HARD";
+const unsigned char *MANAGEMENT_QUERY  = (unsigned char*) "QUERY";
+const unsigned char *MANAGEMENT_CREATE = (unsigned char*) "CREATE";
+const unsigned char *MANAGEMENT_READ   = (unsigned char*) "READ";
+const unsigned char *MANAGEMENT_UPDATE = (unsigned char*) "UPDATE";
+const unsigned char *MANAGEMENT_DELETE = (unsigned char*) "DELETE";
 
 
 typedef enum {
@@ -67,10 +65,7 @@ typedef enum {
     QD_ROUTER_OPERATION_CREATE,
     QD_ROUTER_OPERATION_READ,
     QD_ROUTER_OPERATION_UPDATE,
-    QD_ROUTER_OPERATION_DELETE,
-    QD_ROUTER_OPERATION_ADD_CONTAINER,
-    QD_ROUTER_OPERATION_REMOVE_CONTAINER_CLEAN,
-    QD_ROUTER_OPERATION_REMOVE_CONTAINER_HARD
+    QD_ROUTER_OPERATION_DELETE
 } qd_router_operation_type_t;
 
 
@@ -380,8 +375,12 @@ static bool qd_can_handle_request(qd_parsed_field_t           *properties_fld,
         *entity_type = QD_ROUTER_ADDRESS;
     else if (qd_field_iterator_equal(qd_parse_raw(parsed_field), link_entity_type))
         *entity_type = QD_ROUTER_LINK;
-    else if (qd_field_iterator_equal(qd_parse_raw(parsed_field), route_entity_type))
-        *entity_type = QD_ROUTER_ROUTE;
+    else if (qd_field_iterator_equal(qd_parse_raw(parsed_field), config_address_entity_type))
+        *entity_type = QD_ROUTER_CONFIG_ADDRESS;
+    else if (qd_field_iterator_equal(qd_parse_raw(parsed_field), link_route_entity_type))
+        *entity_type = QD_ROUTER_CONFIG_LINK_ROUTE;
+    else if (qd_field_iterator_equal(qd_parse_raw(parsed_field), auto_link_entity_type))
+        *entity_type = QD_ROUTER_CONFIG_AUTO_LINK;
     else
         return false;
 
@@ -401,12 +400,6 @@ static bool qd_can_handle_request(qd_parsed_field_t           *properties_fld,
         (*operation_type) = QD_ROUTER_OPERATION_UPDATE;
     else if (qd_field_iterator_equal(qd_parse_raw(parsed_field), MANAGEMENT_DELETE))
         (*operation_type) = QD_ROUTER_OPERATION_DELETE;
-    else if (qd_field_iterator_equal(qd_parse_raw(parsed_field), MANAGEMENT_ADD_CONTAINER) && *entity_type == QD_ROUTER_ROUTE)
-        (*operation_type) = QD_ROUTER_OPERATION_ADD_CONTAINER;
-    else if (qd_field_iterator_equal(qd_parse_raw(parsed_field), MANAGEMENT_REMOVE_CONTAINER_CLEAN) && *entity_type == QD_ROUTER_ROUTE)
-        (*operation_type) = QD_ROUTER_OPERATION_REMOVE_CONTAINER_CLEAN;
-    else if (qd_field_iterator_equal(qd_parse_raw(parsed_field), MANAGEMENT_REMOVE_CONTAINER_HARD) && *entity_type == QD_ROUTER_ROUTE)
-        (*operation_type) = QD_ROUTER_OPERATION_REMOVE_CONTAINER_HARD;
     else
         // This is an unknown operation type. cannot be handled, return false.
         return false;
@@ -466,10 +459,6 @@ void qdr_management_agent_on_message(void *context, qd_message_t *msg, int unuse
         case QD_ROUTER_OPERATION_DELETE:
             qd_core_agent_delete_handler(core, msg, entity_type, operation_type, identity_iter, name_iter);
             break;
-        case QD_ROUTER_OPERATION_ADD_CONTAINER:
-        case QD_ROUTER_OPERATION_REMOVE_CONTAINER_CLEAN:
-        case QD_ROUTER_OPERATION_REMOVE_CONTAINER_HARD:
-            break;
         }
     } else {
         //


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