Author: tross
Date: Fri Jan 30 16:33:24 2015
New Revision: 1656050

URL: http://svn.apache.org/r1656050
Log:
DISPATCH-6 - Progress toward link-attach-routing.
 - Renamed the configuration object "linkRoutePattern"
 - Added all the code for managing the lifecycle of external containers:
   - When a container (broker) is connected, the pattern addresses are 
established
     on the connected router and propagated to the non-connected routers.
   - When the container connection is lost, the pattern addresses are removed 
and
     the removal is propagated.

Added:
    qpid/dispatch/trunk/src/lrp.c
      - copied, changed from r1656042, qpid/dispatch/trunk/src/ext_container.c
    qpid/dispatch/trunk/src/lrp_private.h
      - copied, changed from r1655635, 
qpid/dispatch/trunk/src/ext_container_private.h
Removed:
    qpid/dispatch/trunk/src/ext_container.c
    qpid/dispatch/trunk/src/ext_container_private.h
Modified:
    qpid/dispatch/trunk/include/qpid/dispatch/connection_manager.h
    qpid/dispatch/trunk/python/qpid_dispatch/management/qdrouter.json
    qpid/dispatch/trunk/python/qpid_dispatch_internal/dispatch_c.py
    qpid/dispatch/trunk/python/qpid_dispatch_internal/management/agent.py
    qpid/dispatch/trunk/python/qpid_dispatch_internal/management/config.py
    qpid/dispatch/trunk/src/CMakeLists.txt
    qpid/dispatch/trunk/src/dispatch.c
    qpid/dispatch/trunk/src/dispatch_private.h
    qpid/dispatch/trunk/src/router_config.c
    qpid/dispatch/trunk/src/router_node.c
    qpid/dispatch/trunk/src/router_private.h
    qpid/dispatch/trunk/tests/config-2-broker/A.conf

Modified: qpid/dispatch/trunk/include/qpid/dispatch/connection_manager.h
URL: 
http://svn.apache.org/viewvc/qpid/dispatch/trunk/include/qpid/dispatch/connection_manager.h?rev=1656050&r1=1656049&r2=1656050&view=diff
==============================================================================
--- qpid/dispatch/trunk/include/qpid/dispatch/connection_manager.h (original)
+++ qpid/dispatch/trunk/include/qpid/dispatch/connection_manager.h Fri Jan 30 
16:33:24 2015
@@ -118,6 +118,12 @@ void *qd_config_connector_context(qd_con
 void qd_config_connector_set_context(qd_config_connector_t *cc, void *context);
 
 
+/**
+ * Get the connector's name.
+ *
+ * @param cc Connector handle
+ * @return The name of the connector
+ */
 const char *qd_config_connector_name(qd_config_connector_t *cc);
 
 #endif

Modified: qpid/dispatch/trunk/python/qpid_dispatch/management/qdrouter.json
URL: 
http://svn.apache.org/viewvc/qpid/dispatch/trunk/python/qpid_dispatch/management/qdrouter.json?rev=1656050&r1=1656049&r2=1656050&view=diff
==============================================================================
--- qpid/dispatch/trunk/python/qpid_dispatch/management/qdrouter.json (original)
+++ qpid/dispatch/trunk/python/qpid_dispatch/management/qdrouter.json Fri Jan 
30 16:33:24 2015
@@ -433,8 +433,8 @@
             }
         },
 
-        "externalContainer": {
-            "description":"A remote AMQP container that holds nodes that are 
endpoints for routed links.",
+        "linkRoutePattern": {
+            "description":"A pattern to match a connected container to 
endpoints for routed links.",
             "extends": "configurationEntity",
             "operations": ["CREATE"],
             "attributes": {

Modified: qpid/dispatch/trunk/python/qpid_dispatch_internal/dispatch_c.py
URL: 
http://svn.apache.org/viewvc/qpid/dispatch/trunk/python/qpid_dispatch_internal/dispatch_c.py?rev=1656050&r1=1656049&r2=1656050&view=diff
==============================================================================
--- qpid/dispatch/trunk/python/qpid_dispatch_internal/dispatch_c.py (original)
+++ qpid/dispatch/trunk/python/qpid_dispatch_internal/dispatch_c.py Fri Jan 30 
16:33:24 2015
@@ -52,7 +52,7 @@ class QdDll(ctypes.PyDLL):
         self._prototype(self.qd_dispatch_configure_connector, 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_waypoint, None, 
[self.qd_dispatch_p, py_object])
-        self._prototype(self.qd_dispatch_configure_external_container, 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_set_agent, None, [self.qd_dispatch_p, 
py_object])
 
         self._prototype(self.qd_router_setup_late, None, [self.qd_dispatch_p])

Modified: qpid/dispatch/trunk/python/qpid_dispatch_internal/management/agent.py
URL: 
http://svn.apache.org/viewvc/qpid/dispatch/trunk/python/qpid_dispatch_internal/management/agent.py?rev=1656050&r1=1656049&r2=1656050&view=diff
==============================================================================
--- qpid/dispatch/trunk/python/qpid_dispatch_internal/management/agent.py 
(original)
+++ qpid/dispatch/trunk/python/qpid_dispatch_internal/management/agent.py Fri 
Jan 30 16:33:24 2015
@@ -244,10 +244,9 @@ class WaypointEntity(AgentEntity):
         self._qd.qd_dispatch_configure_waypoint(self._dispatch, self)
         self._qd.qd_waypoint_activate_all(self._dispatch)
 
-
-class ExternalContainerEntity(AgentEntity):
+class LinkRoutePatternEntity(AgentEntity):
     def create(self):
-        self._qd.qd_dispatch_configure_external_container(self._dispatch, self)
+        self._qd.qd_dispatch_configure_lrp(self._dispatch, self)
 
 
 class DummyEntity(AgentEntity):

Modified: qpid/dispatch/trunk/python/qpid_dispatch_internal/management/config.py
URL: 
http://svn.apache.org/viewvc/qpid/dispatch/trunk/python/qpid_dispatch_internal/management/config.py?rev=1656050&r1=1656049&r2=1656050&view=diff
==============================================================================
--- qpid/dispatch/trunk/python/qpid_dispatch_internal/management/config.py 
(original)
+++ qpid/dispatch/trunk/python/qpid_dispatch_internal/management/config.py Fri 
Jan 30 16:33:24 2015
@@ -154,7 +154,7 @@ def configure_dispatch(dispatch, lib_han
     qd.qd_router_setup_late(dispatch) # Actions requiring active management 
agent.
 
     # Remaining configuration
-    for t in "fixedAddress", "listener", "connector", "waypoint", 
"externalContainer":
+    for t in "fixedAddress", "listener", "connector", "waypoint", 
"linkRoutePattern":
         for a in config.by_type(t): configure(a)
     for e in config.entities:
         configure(e)

Modified: qpid/dispatch/trunk/src/CMakeLists.txt
URL: 
http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/CMakeLists.txt?rev=1656050&r1=1656049&r2=1656050&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/CMakeLists.txt (original)
+++ qpid/dispatch/trunk/src/CMakeLists.txt Fri Jan 30 16:33:24 2015
@@ -54,7 +54,7 @@ set(qpid_dispatch_SOURCES
   dispatch.c
   entity.c
   entity_cache.c
-  ext_container.c
+  lrp.c
   hash.c
   iovec.c
   iterator.c

Modified: qpid/dispatch/trunk/src/dispatch.c
URL: 
http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/dispatch.c?rev=1656050&r1=1656049&r2=1656050&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/dispatch.c (original)
+++ qpid/dispatch/trunk/src/dispatch.c Fri Jan 30 16:33:24 2015
@@ -125,9 +125,9 @@ qd_error_t qd_dispatch_configure_waypoin
     return qd_error_code();
 }
 
-qd_error_t qd_dispatch_configure_external_container(qd_dispatch_t *qd, 
qd_entity_t *entity) {
+qd_error_t qd_dispatch_configure_lrp(qd_dispatch_t *qd, qd_entity_t *entity) {
     if (!qd->router) return qd_error(QD_ERROR_NOT_FOUND, "No router 
available");
-    qd_router_configure_external_container(qd->router, entity);
+    qd_router_configure_lrp(qd->router, entity);
     return qd_error_code();
 }
 

Modified: qpid/dispatch/trunk/src/dispatch_private.h
URL: 
http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/dispatch_private.h?rev=1656050&r1=1656049&r2=1656050&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/dispatch_private.h (original)
+++ qpid/dispatch/trunk/src/dispatch_private.h Fri Jan 30 16:33:24 2015
@@ -23,18 +23,20 @@
 // The following declarations are for types that are shared between modules 
yet are
 // not in the public API.
 //
-typedef struct qd_server_t             qd_server_t;
-typedef struct qd_container_t          qd_container_t;
-typedef struct qd_router_t             qd_router_t;
-typedef struct qd_waypoint_t           qd_waypoint_t;
-typedef struct qd_external_container_t qd_external_container_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;
-typedef struct qd_router_link_ref_t    qd_router_link_ref_t;
-typedef struct qd_router_conn_t        qd_router_conn_t;
-typedef struct qd_config_phase_t       qd_config_phase_t;
-typedef struct qd_config_address_t     qd_config_address_t;
+typedef struct qd_server_t           qd_server_t;
+typedef struct qd_container_t        qd_container_t;
+typedef struct qd_router_t           qd_router_t;
+typedef struct qd_waypoint_t         qd_waypoint_t;
+typedef struct qd_lrp_container_t    qd_lrp_container_t;
+typedef struct qd_lrp_t              qd_lrp_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;
+typedef struct qd_router_link_ref_t  qd_router_link_ref_t;
+typedef struct qd_router_lrp_ref_t   qd_router_lrp_ref_t;
+typedef struct qd_router_conn_t      qd_router_conn_t;
+typedef struct qd_config_phase_t     qd_config_phase_t;
+typedef struct qd_config_address_t   qd_config_address_t;
 
 #include <qpid/dispatch/container.h>
 #include <qpid/dispatch/router.h>
@@ -94,9 +96,9 @@ qd_error_t qd_dispatch_configure_address
 qd_error_t qd_dispatch_configure_waypoint(qd_dispatch_t *qd, qd_entity_t 
*entity);
 
 /**
- * Configure an external container, must be called after qd_dispatch_prepare
+ * Configure a link-route-pattern, must be called after qd_dispatch_prepare
  */
-qd_error_t qd_dispatch_configure_external_container(qd_dispatch_t *qd, 
qd_entity_t *entity);
+qd_error_t qd_dispatch_configure_lrp(qd_dispatch_t *qd, qd_entity_t *entity);
 
 /**
  * \brief Configure the logging module from the

Copied: qpid/dispatch/trunk/src/lrp.c (from r1656042, 
qpid/dispatch/trunk/src/ext_container.c)
URL: 
http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/lrp.c?p2=qpid/dispatch/trunk/src/lrp.c&p1=qpid/dispatch/trunk/src/ext_container.c&r1=1656042&r2=1656050&rev=1656050&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/ext_container.c (original)
+++ qpid/dispatch/trunk/src/lrp.c Fri Jan 30 16:33:24 2015
@@ -25,82 +25,148 @@
 #include <memory.h>
 #include <stdio.h>
 
-struct qd_external_container_t {
-    DEQ_LINKS(qd_external_container_t);
-    qd_dispatch_t *qd;
-    char          *prefix;
-    char          *connector_name;
-    qd_timer_t    *timer;
-};
+static const char qd_link_route_addr_prefix = 'C';
 
-DEQ_DECLARE(qd_external_container_t, qd_external_container_list_t);
-
-static qd_external_container_list_t ec_list = DEQ_EMPTY;
-
-
-static void qd_external_container_open_handler(void *context, qd_connection_t 
*conn)
+static void qd_lrpc_open_handler(void *context, qd_connection_t *conn)
 {
-    //const char *name = (char*) context;
-}
+    qd_lrp_container_t *lrpc   = (qd_lrp_container_t*) context;
+    qd_lrp_t           *lrp    = DEQ_HEAD(lrpc->lrps);
+    qd_router_t        *router = lrpc->qd->router;
+
+    while (lrp) {
+        qd_address_t        *addr;
+        qd_field_iterator_t *iter;
+        bool                 propagate;
+        char                 unused;
+
+        qd_log(router->log_source, QD_LOG_INFO, "Activating Prefix '%s' for 
routed links to '%s'",
+               lrp->prefix, qd_config_connector_name(lrpc->cc));
+
+        //
+        // Create an address iterator for the prefix address with the namespace
+        // prefix for link-attach routed addresses.
+        //
+        iter = qd_field_iterator_string(lrp->prefix, ITER_VIEW_ADDRESS_HASH);
+        qd_field_iterator_override_prefix(iter, qd_link_route_addr_prefix);
+
+        //
+        // Find the address in the router's hash table.  If not found, create 
one
+        // and hash it into the table.
+        //
+        sys_mutex_lock(router->lock);
+        qd_hash_retrieve(router->addr_hash, iter, (void**) &addr);
+        if (!addr) {
+            addr = qd_address();
+            qd_hash_insert(router->addr_hash, iter, addr, &addr->hash_handle);
+            DEQ_INSERT_TAIL(router->addrs, addr);
+            addr->semantics = router_semantics_for_addr(router, iter, '\0', 
&unused);
+            qd_entity_cache_add(QD_ROUTER_ADDRESS_TYPE, addr);
+        }
+
+        //
+        // Link the LRP record into the address as a local endpoint for routed 
link-attaches.
+        // If this is the first instance for this address, flag the address 
for propagation
+        // across the network.
+        //
+        qd_router_add_lrp_ref_LH(&addr->lrps, lrp);
+        propagate = DEQ_SIZE(addr->lrps) == 1;
+        sys_mutex_unlock(router->lock);
+
+        //
+        // Propagate the address if appropriate
+        //
+        if (propagate)
+            qd_router_mobile_added(router, iter);
 
-
-static void qd_external_container_close_handler(void *context, qd_connection_t 
*conn)
-{
-    //const char *name = (char*) context;
+        qd_field_iterator_free(iter);
+        lrp = DEQ_NEXT(lrp);
+    }
 }
 
 
-static void qd_external_container_timer_handler(void *context)
+static void qd_lrpc_close_handler(void *context, qd_connection_t *conn)
 {
-    qd_external_container_t *ec = (qd_external_container_t*) context;
-    qd_config_connector_t   *cc = qd_connection_manager_find_on_demand(ec->qd, 
ec->connector_name);
-    if (cc) {
-        qd_connection_manager_set_handlers(cc,
-                                           qd_external_container_open_handler,
-                                           qd_external_container_close_handler,
-                                           (void*) ec->connector_name);
-        qd_connection_manager_start_on_demand(ec->qd, cc);
+    qd_lrp_container_t *lrpc   = (qd_lrp_container_t*) context;
+    qd_lrp_t           *lrp    = DEQ_HEAD(lrpc->lrps);
+    qd_router_t        *router = lrpc->qd->router;
+
+    while (lrp) {
+        qd_address_t        *addr;
+        qd_field_iterator_t *iter;
+        bool                 propagate = false;
+
+        qd_log(router->log_source, QD_LOG_INFO, "Removing Prefix '%s' for 
routed links to '%s'",
+               lrp->prefix, qd_config_connector_name(lrpc->cc));
+
+        //
+        // Create an address iterator for the prefix address with the namespace
+        // prefix for link-attach routed addresses.
+        //
+        iter = qd_field_iterator_string(lrp->prefix, ITER_VIEW_ADDRESS_HASH);
+        qd_field_iterator_override_prefix(iter, qd_link_route_addr_prefix);
+
+        //
+        // Find the address in the router's hash table.
+        //
+        sys_mutex_lock(router->lock);
+        qd_hash_retrieve(router->addr_hash, iter, (void**) &addr);
+        if (addr) {
+            //
+            // Unlink the lrp from the address.  If this is the last lrp in 
the address, we need
+            // to tell the other routers.
+            //
+            qd_router_del_lrp_ref_LH(&addr->lrps, lrp);
+            propagate = DEQ_SIZE(addr->lrps) == 0;
+        }
+        sys_mutex_unlock(router->lock);
+
+        //
+        // Propagate the address if appropriate
+        //
+        if (propagate) {
+            char *text = (char*) qd_field_iterator_copy(iter);
+            qd_router_mobile_removed(router, text);
+            free(text);
+        }
+
+        qd_field_iterator_free(iter);
+        lrp = DEQ_NEXT(lrp);
     }
 }
 
 
-qd_external_container_t *qd_external_container(qd_dispatch_t *qd, const char 
*prefix, const char *connector_name)
+void qd_lrpc_timer_handler(void *context)
 {
-    qd_external_container_t *ec = NEW(qd_external_container_t);
-
-    if (ec) {
-        DEQ_ITEM_INIT(ec);
-        ec->qd             = qd;
-        ec->prefix         = strdup(prefix);
-        ec->connector_name = strdup(connector_name);
-        ec->timer          = qd_timer(qd, qd_external_container_timer_handler, 
ec);
-        DEQ_INSERT_TAIL(ec_list, ec);
-        qd_timer_schedule(ec->timer, 0);
-    }
-
-    return ec;
+    qd_lrp_container_t *lrpc = (qd_lrp_container_t*) context;
+    qd_connection_manager_set_handlers(lrpc->cc,
+                                       qd_lrpc_open_handler,
+                                       qd_lrpc_close_handler,
+                                       (void*) lrpc);
+    qd_connection_manager_start_on_demand(lrpc->qd, lrpc->cc);
 }
 
 
-void qd_external_container_free(qd_external_container_t *ec)
+qd_lrp_t *qd_lrp_LH(const char *prefix, qd_lrp_container_t *lrpc)
 {
-    if (ec) {
-        free(ec->prefix);
-        free(ec->connector_name);
-        qd_timer_free(ec->timer);
-        DEQ_REMOVE(ec_list, ec);
-        free(ec);
+    qd_lrp_t *lrp = NEW(qd_lrp_t);
+
+    if (lrp) {
+        DEQ_ITEM_INIT(lrp);
+        lrp->prefix    = strdup(prefix);
+        lrp->container = lrpc;
+        DEQ_INSERT_TAIL(lrpc->lrps, lrp);
     }
+
+    return lrp;
 }
 
 
-void qd_external_container_free_all(void)
+void qd_lrp_free(qd_lrp_t *lrp)
 {
-    qd_external_container_t *ec = DEQ_HEAD(ec_list);
-    while (ec) {
-        DEQ_REMOVE_HEAD(ec_list);
-        qd_external_container_free(ec);
-        ec = DEQ_HEAD(ec_list);
+    if (lrp) {
+        free(lrp->prefix);
+        DEQ_REMOVE(lrp->container->lrps, lrp);
+        free(lrp);
     }
 }
 

Copied: qpid/dispatch/trunk/src/lrp_private.h (from r1655635, 
qpid/dispatch/trunk/src/ext_container_private.h)
URL: 
http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/lrp_private.h?p2=qpid/dispatch/trunk/src/lrp_private.h&p1=qpid/dispatch/trunk/src/ext_container_private.h&r1=1655635&r2=1656050&rev=1656050&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/ext_container_private.h (original)
+++ qpid/dispatch/trunk/src/lrp_private.h Fri Jan 30 16:33:24 2015
@@ -1,5 +1,5 @@
-#ifndef __ext_container_private_h__
-#define __ext_container_private_h__ 1
+#ifndef __lrp_private_h__
+#define __lrp_private_h__ 1
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -24,18 +24,17 @@
 /**
  * @file
  *
- * An external container is an object that defines an address prefix for 
link-routing
+ * An link-route-pattern is an object that defines an address prefix for 
link-routing
  * and associates that prefix with an on-demand connector.
  *
  * The address prefix is propagated across the network and can be used as a 
target for
- * routed links destined for this external container.
+ * routed links destined for this LRP.
  */
 
-qd_external_container_t *qd_external_container(qd_dispatch_t *qd, const char 
*prefix, const char *connector_name);
+qd_lrp_t *qd_lrp_LH(const char *prefix, qd_lrp_container_t *lrpc);
 
-void qd_external_container_free(qd_external_container_t *ec);
-
-void qd_external_container_free_all(void);
+void qd_lrp_free(qd_lrp_t *lrp);
 
+void qd_lrpc_timer_handler(void *context);
 
 #endif

Modified: qpid/dispatch/trunk/src/router_config.c
URL: 
http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/router_config.c?rev=1656050&r1=1656049&r2=1656050&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/router_config.c (original)
+++ qpid/dispatch/trunk/src/router_config.c Fri Jan 30 16:33:24 2015
@@ -22,7 +22,7 @@
 #include <qpid/dispatch/log.h>
 #include "dispatch_private.h"
 #include "router_private.h"
-#include "ext_container_private.h"
+#include "lrp_private.h"
 #include "entity.h"
 #include "schema_enum.h"
 
@@ -136,24 +136,64 @@ qd_error_t qd_router_configure_waypoint(
 }
 
 
-qd_error_t qd_router_configure_external_container(qd_router_t *router, 
qd_entity_t *entity)
+qd_error_t qd_router_configure_lrp(qd_router_t *router, qd_entity_t *entity)
 {
-
     char *prefix    = qd_entity_get_string(entity, "prefix"); QD_ERROR_RET();
     char *connector = qd_entity_get_string(entity, "connector"); 
QD_ERROR_RET();
 
-    qd_external_container_t *ec = qd_external_container(router->qd, prefix, 
connector);
+    sys_mutex_lock(router->lock);
+    //
+    // Look for an existing lrp_container for the same connector name
+    //
+    qd_lrp_container_t *lrpc = DEQ_HEAD(router->lrp_containers);
+    while (lrpc) {
+        if (strcmp(qd_config_connector_name(lrpc->cc), connector) == 0)
+            break;
+        lrpc = DEQ_NEXT(lrpc);
+    }
+
+    //
+    // If no lrp_container was found, create one and add it to the list
+    //
+    if (lrpc == 0) {
+        qd_config_connector_t *cc = 
qd_connection_manager_find_on_demand(router->qd, connector);
+        if (cc) {
+            lrpc = NEW(qd_lrp_container_t);
+            DEQ_ITEM_INIT(lrpc);
+            lrpc->qd    = router->qd;
+            lrpc->cc    = cc;
+            lrpc->timer = qd_timer(router->qd, qd_lrpc_timer_handler, lrpc);
+            lrpc->conn  = 0;
+            DEQ_INIT(lrpc->lrps);
+            DEQ_INSERT_TAIL(router->lrp_containers, lrpc);
 
-    if (!ec) {
+            qd_timer_schedule(lrpc->timer, 0);
+        }
+    }
+
+    if (lrpc == 0) {
+        sys_mutex_unlock(router->lock);
         free(prefix);
         free(connector);
-        return qd_error(QD_ERROR_CONFIG, "Failed to create external container: 
prefix=%s connector=%s",
+        return qd_error(QD_ERROR_CONFIG, "Link-route-pattern configured with 
unknown connector: %s", connector);
+    }
+
+    qd_lrp_t *lrp = qd_lrp_LH(prefix, lrpc);
+
+    if (!lrp) {
+        sys_mutex_unlock(router->lock);
+        free(prefix);
+        free(connector);
+        return qd_error(QD_ERROR_CONFIG, "Failed to create link-route-pattern: 
prefix=%s connector=%s",
                         prefix, connector);
     }
 
+    sys_mutex_unlock(router->lock);
+
     qd_log(router->log_source, QD_LOG_INFO,
-           "Configured External Container: prefix=%s connector=%s",
+           "Configured Link-route-pattern: prefix=%s connector=%s",
            prefix, connector);
+
     free(prefix);
     free(connector);
     return qd_error_code();
@@ -181,7 +221,13 @@ void qd_router_configure_free(qd_router_
         free(wp);
     }
 
-    qd_external_container_free_all();
+    for (qd_lrp_container_t *lrpc = DEQ_HEAD(router->lrp_containers); lrpc; 
lrpc = DEQ_HEAD(router->lrp_containers)) {
+        for (qd_lrp_t *lrp = DEQ_HEAD(lrpc->lrps); lrp; lrp = 
DEQ_HEAD(lrpc->lrps))
+            qd_lrp_free(lrp);
+        qd_timer_free(lrpc->timer);
+        DEQ_REMOVE_HEAD(router->lrp_containers);
+        free(lrpc);
+    }
 }
 
 

Modified: qpid/dispatch/trunk/src/router_node.c
URL: 
http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/router_node.c?rev=1656050&r1=1656049&r2=1656050&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/router_node.c (original)
+++ qpid/dispatch/trunk/src/router_node.c Fri Jan 30 16:33:24 2015
@@ -59,6 +59,7 @@ ALLOC_DEFINE(qd_router_link_t);
 ALLOC_DEFINE(qd_router_node_t);
 ALLOC_DEFINE(qd_router_ref_t);
 ALLOC_DEFINE(qd_router_link_ref_t);
+ALLOC_DEFINE(qd_router_lrp_ref_t);
 ALLOC_DEFINE(qd_address_t);
 ALLOC_DEFINE(qd_router_conn_t);
 
@@ -66,6 +67,7 @@ qd_address_t* qd_address() {
     qd_address_t* addr = new_qd_address_t();
     memset(addr, 0, sizeof(qd_address_t));
     DEQ_ITEM_INIT(addr);
+    DEQ_INIT(addr->lrps);
     DEQ_INIT(addr->rlinks);
     DEQ_INIT(addr->rnodes);
     return addr;
@@ -120,6 +122,29 @@ void qd_router_del_node_ref_LH(qd_router
 }
 
 
+void qd_router_add_lrp_ref_LH(qd_router_lrp_ref_list_t *ref_list, qd_lrp_t 
*lrp)
+{
+    qd_router_lrp_ref_t *ref = new_qd_router_lrp_ref_t();
+    DEQ_ITEM_INIT(ref);
+    ref->lrp = lrp;
+    DEQ_INSERT_TAIL(*ref_list, ref);
+}
+
+
+void qd_router_del_lrp_ref_LH(qd_router_lrp_ref_list_t *ref_list, qd_lrp_t 
*lrp)
+{
+    qd_router_lrp_ref_t *ref = DEQ_HEAD(*ref_list);
+    while (ref) {
+        if (ref->lrp == lrp) {
+            DEQ_REMOVE(*ref_list, ref);
+            free_qd_router_lrp_ref_t(ref);
+            break;
+        }
+        ref = DEQ_NEXT(ref);
+    }
+}
+
+
 /**
  * Check an address to see if it no longer has any associated destinations.
  * Depending on its policy, the address may be eligible for being closed out
@@ -1424,6 +1449,7 @@ qd_router_t *qd_router(qd_dispatch_t *qd
 
     DEQ_INIT(router->links);
     DEQ_INIT(router->routers);
+    DEQ_INIT(router->lrp_containers);
 
     router->out_links_by_mask_bit = NEW_PTR_ARRAY(qd_router_link_t, 
qd_bitmask_width());
     router->routers_by_mask_bit   = NEW_PTR_ARRAY(qd_router_node_t, 
qd_bitmask_width());

Modified: qpid/dispatch/trunk/src/router_private.h
URL: 
http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/router_private.h?rev=1656050&r1=1656049&r2=1656050&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/router_private.h (original)
+++ qpid/dispatch/trunk/src/router_private.h Fri Jan 30 16:33:24 2015
@@ -38,7 +38,7 @@ void qd_router_python_free(qd_router_t *
 qd_error_t qd_pyrouter_tick(qd_router_t *router);
 qd_error_t qd_router_configure_address(qd_router_t *router, qd_entity_t 
*entity);
 qd_error_t qd_router_configure_waypoint(qd_router_t *router, qd_entity_t 
*entity);
-qd_error_t qd_router_configure_external_container(qd_router_t *router, 
qd_entity_t *entity);
+qd_error_t qd_router_configure_lrp(qd_router_t *router, qd_entity_t *entity);
 
 void qd_router_configure_free(qd_router_t *router);
 
@@ -123,6 +123,36 @@ ALLOC_DECLARE(qd_router_link_ref_t);
 DEQ_DECLARE(qd_router_link_ref_t, qd_router_link_ref_list_t);
 
 
+struct qd_lrp_t {
+    DEQ_LINKS(qd_lrp_t);
+    char               *prefix;
+    qd_lrp_container_t *container;
+};
+
+DEQ_DECLARE(qd_lrp_t, qd_lrp_list_t);
+
+
+struct qd_lrp_container_t {
+    DEQ_LINKS(qd_lrp_container_t);
+    qd_dispatch_t         *qd;
+    qd_config_connector_t *cc;
+    qd_lrp_list_t          lrps;
+    qd_timer_t            *timer;
+    qd_connection_t       *conn;
+};
+
+DEQ_DECLARE(qd_lrp_container_t, qd_lrp_container_list_t);
+
+
+struct qd_router_lrp_ref_t {
+    DEQ_LINKS(qd_router_lrp_ref_t);
+    qd_lrp_t *lrp;
+};
+
+ALLOC_DECLARE(qd_router_lrp_ref_t);
+DEQ_DECLARE(qd_router_lrp_ref_t, qd_router_lrp_ref_list_t);
+
+
 struct qd_router_conn_t {
     int ref_count;
     int mask_bit;
@@ -136,6 +166,7 @@ struct qd_address_t {
     DEQ_LINKS(qd_address_t);
     qd_router_message_cb_t     handler;          ///< In-Process Consumer
     void                      *handler_context;  ///< In-Process Consumer 
context
+    qd_router_lrp_ref_list_t   lrps;             ///< Local link-route 
destinations
     qd_router_link_ref_list_t  rlinks;           ///< Locally-Connected 
Consumers
     qd_router_ref_list_t       rnodes;           ///< Remotely-Connected 
Consumers
     qd_hash_handle_t          *hash_handle;      ///< Linkage back to the hash 
table entry
@@ -224,6 +255,7 @@ struct qd_router_t {
 
     qd_router_link_list_t     links;
     qd_router_node_list_t     routers;
+    qd_lrp_container_list_t   lrp_containers;
     qd_router_link_t        **out_links_by_mask_bit;
     qd_router_node_t        **routers_by_mask_bit;
 
@@ -245,6 +277,9 @@ void qd_router_del_link_ref_LH(qd_router
 void qd_router_add_node_ref_LH(qd_router_ref_list_t *ref_list, 
qd_router_node_t *rnode);
 void qd_router_del_node_ref_LH(qd_router_ref_list_t *ref_list, 
qd_router_node_t *rnode);
 
+void qd_router_add_lrp_ref_LH(qd_router_lrp_ref_list_t *ref_list, qd_lrp_t 
*lrp);
+void qd_router_del_lrp_ref_LH(qd_router_lrp_ref_list_t *ref_list, qd_lrp_t 
*lrp);
+
 void qd_router_mobile_added(qd_router_t *router, qd_field_iterator_t *iter);
 void qd_router_mobile_removed(qd_router_t *router, const char *addr);
 void qd_router_link_lost(qd_router_t *router, int link_mask_bit);

Modified: qpid/dispatch/trunk/tests/config-2-broker/A.conf
URL: 
http://svn.apache.org/viewvc/qpid/dispatch/trunk/tests/config-2-broker/A.conf?rev=1656050&r1=1656049&r2=1656050&view=diff
==============================================================================
--- qpid/dispatch/trunk/tests/config-2-broker/A.conf (original)
+++ qpid/dispatch/trunk/tests/config-2-broker/A.conf Fri Jan 30 16:33:24 2015
@@ -72,8 +72,13 @@ connector {
     sasl-mechanisms: ANONYMOUS
 }
 
-externalContainer {
-    prefix: queue/
+linkRoutePattern {
+    prefix: queue1/
+    connector: broker
+}
+
+linkRoutePattern {
+    prefix: queue2/
     connector: broker
 }
 



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to