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/19 00:06:49 UTC

[31/50] [abbrv] qpid-dispatch git commit: DISPATCH-179 - Added configuration and management hooks for config.linkRoute

DISPATCH-179 - Added configuration and management hooks for config.linkRoute


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

Branch: refs/heads/master
Commit: 56c5a93fa9af2d4d7f219a268a1cacb67ce7a085
Parents: 7c2d4e6
Author: Ted Ross <tr...@redhat.com>
Authored: Wed Mar 16 09:36:34 2016 -0400
Committer: Ted Ross <tr...@redhat.com>
Committed: Wed Mar 16 09:36:34 2016 -0400

----------------------------------------------------------------------
 python/qpid_dispatch/management/qdrouter.json |   7 +-
 src/CMakeLists.txt                            |   1 +
 src/router_config.c                           |  54 +--
 src/router_core/agent.c                       |  17 +-
 src/router_core/agent_config_link_route.c     | 408 +++++++++++++++++++++
 src/router_core/agent_config_link_route.h     |  35 ++
 src/router_core/route_control.c               |   7 +-
 src/router_core/route_control.h               |   2 +-
 8 files changed, 495 insertions(+), 36 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/56c5a93f/python/qpid_dispatch/management/qdrouter.json
----------------------------------------------------------------------
diff --git a/python/qpid_dispatch/management/qdrouter.json b/python/qpid_dispatch/management/qdrouter.json
index 40f3e19..61d3642 100644
--- a/python/qpid_dispatch/management/qdrouter.json
+++ b/python/qpid_dispatch/management/qdrouter.json
@@ -886,7 +886,7 @@
                     "create": true,
                     "required": false
                 },
-                "connectionName": {
+                "connection": {
                     "type": "string",
                     "description": "The name from a connector or listener",
                     "create": true,
@@ -903,8 +903,7 @@
                     "type": ["in", "out"],
                     "description": "The permitted direction of links: 'in' means client senders; 'out' means client receivers",
                     "create": true,
-                    "required": false,
-                    "default": "both"
+                    "required": true
                 }
             }
         },
@@ -938,7 +937,7 @@
                     "create": true,
                     "required": false
                 },
-                "connectionName": {
+                "connection": {
                     "type": "string",
                     "description": "The name from a connector or listener",
                     "create": true,

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/56c5a93f/src/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 9ae6d08..fbcbd6e 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -67,6 +67,7 @@ set(qpid_dispatch_SOURCES
   router_core/agent.c
   router_core/agent_address.c
   router_core/agent_config_address.c
+  router_core/agent_config_link_route.c
   router_core/agent_link.c
   router_core/connections.c
   router_core/error.c

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/56c5a93f/src/router_config.c
----------------------------------------------------------------------
diff --git a/src/router_config.c b/src/router_config.c
index d22f8c1..202ee9f 100644
--- a/src/router_config.c
+++ b/src/router_config.c
@@ -128,12 +128,8 @@ qd_error_t qd_router_configure_waypoint(qd_router_t *router, qd_entity_t *entity
 }
 
 
-qd_error_t qd_router_configure_lrp(qd_router_t *router, qd_entity_t *entity)
+static void qd_router_add_link_route(qdr_core_t *core, const char *prefix, const char *connector, const char* dir)
 {
-    char *prefix    = qd_entity_get_string(entity, "prefix");    QD_ERROR_RET();
-    char *connector = qd_entity_get_string(entity, "connector"); QD_ERROR_RET();
-    char *direction = qd_entity_get_string(entity, "dir");       QD_ERROR_RET();
-
     //
     // Formulate this configuration as a router.route and create it through the core management API.
     //
@@ -143,10 +139,10 @@ qd_error_t qd_router_configure_lrp(qd_router_t *router, qd_entity_t *entity)
     qd_compose_insert_string(body, prefix);
 
     qd_compose_insert_string(body, "dir");
-    qd_compose_insert_string(body, direction);
+    qd_compose_insert_string(body, dir);
 
     if (connector) {
-        qd_compose_insert_string(body, "connectionName");
+        qd_compose_insert_string(body, "connection");
         qd_compose_insert_string(body, connector);
     }
 
@@ -167,7 +163,21 @@ 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_CONFIG_LINK_ROUTE, 0, in_body, 0);
+    qdr_manage_create(core, 0, QD_ROUTER_CONFIG_LINK_ROUTE, 0, in_body, 0);
+}
+
+
+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();
+    char *direction = qd_entity_get_string(entity, "dir");       QD_ERROR_RET();
+
+    if (strcmp("in", direction) == 0 || strcmp("both", direction) == 0)
+        qd_router_add_link_route(router->router_core, prefix, connector, "in");
+
+    if (strcmp("out", direction) == 0 || strcmp("both", direction) == 0)
+        qd_router_add_link_route(router->router_core, prefix, connector, "out");
 
     free(prefix);
     free(connector);
@@ -248,12 +258,12 @@ qd_error_t qd_router_configure_address(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 *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();
+    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, "connection", 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.
@@ -277,7 +287,7 @@ qd_error_t qd_router_configure_link_route(qd_router_t *router, qd_entity_t *enti
     }
 
     if (c_name) {
-        qd_compose_insert_string(body, "connectionName");
+        qd_compose_insert_string(body, "connection");
         qd_compose_insert_string(body, c_name);
     }
 
@@ -323,12 +333,12 @@ qd_error_t qd_router_configure_link_route(qd_router_t *router, qd_entity_t *enti
 
 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();
+    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, "connection", 0);  QD_ERROR_RET();
 
     //
     // Formulate this configuration as a route and create it through the core management API.
@@ -362,7 +372,7 @@ qd_error_t qd_router_configure_auto_link(qd_router_t *router, qd_entity_t *entit
     }
 
     if (c_name) {
-        qd_compose_insert_string(body, "connectionName");
+        qd_compose_insert_string(body, "connection");
         qd_compose_insert_string(body, c_name);
     }
 

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/56c5a93f/src/router_core/agent.c
----------------------------------------------------------------------
diff --git a/src/router_core/agent.c b/src/router_core/agent.c
index 835030c..450293a 100644
--- a/src/router_core/agent.c
+++ b/src/router_core/agent.c
@@ -19,6 +19,7 @@
 
 #include <qpid/dispatch/amqp.h>
 #include "agent_config_address.h"
+#include "agent_config_link_route.h"
 #include "agent_address.h"
 #include "agent_link.h"
 #include "router_core_private.h"
@@ -177,8 +178,8 @@ 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_CONFIG_ADDRESS:    break;
-    case QD_ROUTER_CONFIG_LINK_ROUTE: break;
+    case QD_ROUTER_CONFIG_ADDRESS:    qdr_agent_set_columns(query, attribute_names, qdr_config_address_columns, QDR_CONFIG_ADDRESS_COLUMN_COUNT);  break;
+    case QD_ROUTER_CONFIG_LINK_ROUTE: qdr_agent_set_columns(query, attribute_names, qdr_config_link_route_columns, QDR_CONFIG_LINK_ROUTE_COLUMN_COUNT);  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;
@@ -194,8 +195,8 @@ 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_CONFIG_ADDRESS:    break;
-    case QD_ROUTER_CONFIG_LINK_ROUTE: break;
+    case QD_ROUTER_CONFIG_ADDRESS:    qdr_agent_emit_columns(query, qdr_config_address_columns, QDR_CONFIG_ADDRESS_COLUMN_COUNT); break;
+    case QD_ROUTER_CONFIG_LINK_ROUTE: qdr_agent_emit_columns(query, qdr_config_link_route_columns, QDR_CONFIG_LINK_ROUTE_COLUMN_COUNT); 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;
@@ -339,7 +340,7 @@ static void qdr_manage_create_CT(qdr_core_t *core, qdr_action_t *action, bool di
 
     switch (query->entity_type) {
     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_LINK_ROUTE: qdra_config_link_route_create_CT(core, name, query, in_body); break;
     case QD_ROUTER_CONFIG_AUTO_LINK:  break;
     case QD_ROUTER_CONNECTION:        break;
     case QD_ROUTER_LINK:              break;
@@ -361,7 +362,7 @@ static void qdr_manage_delete_CT(qdr_core_t *core, qdr_action_t *action, bool di
 
     switch (query->entity_type) {
     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_LINK_ROUTE: qdra_config_link_route_delete_CT(core, query, name, identity); break;
     case QD_ROUTER_CONFIG_AUTO_LINK:  break;
     case QD_ROUTER_CONNECTION:        break;
     case QD_ROUTER_LINK:              break;
@@ -403,7 +404,7 @@ 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_CONFIG_ADDRESS:    qdra_config_address_get_first_CT(core, query, offset); break;
-        case QD_ROUTER_CONFIG_LINK_ROUTE: break;
+        case QD_ROUTER_CONFIG_LINK_ROUTE: qdra_config_link_route_get_first_CT(core, query, offset); 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;
@@ -422,7 +423,7 @@ 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_CONFIG_ADDRESS:    qdra_config_address_get_next_CT(core, query); break;
-        case QD_ROUTER_CONFIG_LINK_ROUTE: break;
+        case QD_ROUTER_CONFIG_LINK_ROUTE: qdra_config_link_route_get_next_CT(core, query); 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;

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/56c5a93f/src/router_core/agent_config_link_route.c
----------------------------------------------------------------------
diff --git a/src/router_core/agent_config_link_route.c b/src/router_core/agent_config_link_route.c
new file mode 100644
index 0000000..839dab7
--- /dev/null
+++ b/src/router_core/agent_config_link_route.c
@@ -0,0 +1,408 @@
+/*
+ * 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_link_route.h"
+#include "route_control.h"
+#include <stdio.h>
+
+#define QDR_CONFIG_LINK_ROUTE_NAME          0
+#define QDR_CONFIG_LINK_ROUTE_IDENTITY      1
+#define QDR_CONFIG_LINK_ROUTE_TYPE          2
+#define QDR_CONFIG_LINK_ROUTE_PREFIX        3
+#define QDR_CONFIG_LINK_ROUTE_DISTRIBUTION  4
+#define QDR_CONFIG_LINK_ROUTE_CONNECTION    5
+#define QDR_CONFIG_LINK_ROUTE_CONTAINER_ID  6
+#define QDR_CONFIG_LINK_ROUTE_DIR           7
+
+const char *qdr_config_link_route_columns[] =
+    {"name",
+     "identity",
+     "type",
+     "prefix",
+     "distribution",
+     "connection",
+     "containerId",
+     "dir",
+     0};
+
+
+static void qdr_config_link_route_insert_column_CT(qdr_link_route_t *lr, 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_link_route_columns[col]);
+
+    switch(col) {
+    case QDR_CONFIG_LINK_ROUTE_NAME:
+        if (lr->name)
+            qd_compose_insert_string(body, lr->name);
+        else
+            qd_compose_insert_null(body);
+        break;
+
+    case QDR_CONFIG_LINK_ROUTE_IDENTITY: {
+        char id_str[100];
+        snprintf(id_str, 100, "%ld", lr->identity);
+        qd_compose_insert_string(body, id_str);
+        break;
+    }
+
+    case QDR_CONFIG_LINK_ROUTE_TYPE:
+        qd_compose_insert_string(body, "org.apache.qpid.dispatch.config.link_route");
+        break;
+
+    case QDR_CONFIG_LINK_ROUTE_PREFIX:
+        key = (const char*) qd_hash_key_by_handle(lr->addr->hash_handle);
+        if (key && (key[0] == 'C' || key[0] == 'D'))
+            qd_compose_insert_string(body, &key[1]);
+        else
+            qd_compose_insert_null(body);
+        break;
+
+    case QDR_CONFIG_LINK_ROUTE_DISTRIBUTION:
+        switch (lr->treatment) {
+        case QD_TREATMENT_LINK_BALANCED: text = "linkBalanced"; break;
+        default:
+            text = 0;
+        }
+
+        if (text)
+            qd_compose_insert_string(body, text);
+        else
+            qd_compose_insert_null(body);
+
+        break;
+
+    case QDR_CONFIG_LINK_ROUTE_CONNECTION:
+    case QDR_CONFIG_LINK_ROUTE_CONTAINER_ID:
+        if (lr->conn_id) {
+            key = (const char*) qd_hash_key_by_handle(lr->conn_id->hash_handle);
+            if (key && key[0] == 'L' && col == QDR_CONFIG_LINK_ROUTE_CONNECTION) {
+                qd_compose_insert_string(body, &key[1]);
+                break;
+            }
+            if (key && key[0] == 'C' && col == QDR_CONFIG_LINK_ROUTE_CONTAINER_ID) {
+                qd_compose_insert_string(body, &key[1]);
+                break;
+            }
+        }
+        qd_compose_insert_null(body);
+        break;
+
+    case QDR_CONFIG_LINK_ROUTE_DIR:
+        text = lr->dir == QD_INCOMING ? "in" : "out";
+        qd_compose_insert_string(body, text);
+        break;
+    }
+}
+
+
+static void qdr_agent_write_config_link_route_CT(qdr_query_t *query,  qdr_link_route_t *lr)
+{
+    qd_composed_field_t *body = query->body;
+
+    qd_compose_start_list(body);
+    int i = 0;
+    while (query->columns[i] >= 0) {
+        qdr_config_link_route_insert_column_CT(lr, query->columns[i], body, false);
+        i++;
+    }
+    qd_compose_end_list(body);
+}
+
+
+static void qdr_manage_advance_config_link_route_CT(qdr_query_t *query, qdr_link_route_t *lr)
+{
+    query->next_offset++;
+    lr = DEQ_NEXT(lr);
+    query->more = !!lr;
+}
+
+
+void qdra_config_link_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->link_routes)) {
+        query->more = false;
+        qdr_agent_enqueue_response_CT(core, query);
+        return;
+    }
+
+    //
+    // Run to the object at the offset.
+    //
+    qdr_link_route_t *lr = DEQ_HEAD(core->link_routes);
+    for (int i = 0; i < offset && lr; i++)
+        lr = DEQ_NEXT(lr);
+    assert(lr);
+
+    //
+    // Write the columns of the object into the response body.
+    //
+    qdr_agent_write_config_link_route_CT(query, lr);
+
+    //
+    // Advance to the next link_route
+    //
+    query->next_offset = offset;
+    qdr_manage_advance_config_link_route_CT(query, lr);
+
+    //
+    // Enqueue the response.
+    //
+    qdr_agent_enqueue_response_CT(core, query);
+}
+
+
+void qdra_config_link_route_get_next_CT(qdr_core_t *core, qdr_query_t *query)
+{
+    qdr_link_route_t *lr = 0;
+
+    if (query->next_offset < DEQ_SIZE(core->link_routes)) {
+        lr = DEQ_HEAD(core->link_routes);
+        for (int i = 0; i < query->next_offset && lr; i++)
+            lr = DEQ_NEXT(lr);
+    }
+
+    if (lr) {
+        //
+        // Write the columns of the addr entity into the response body.
+        //
+        qdr_agent_write_config_link_route_CT(query, lr);
+
+        //
+        // Advance to the next object
+        //
+        qdr_manage_advance_config_link_route_CT(query, lr);
+    } else
+        query->more = false;
+
+    //
+    // Enqueue the response.
+    //
+    qdr_agent_enqueue_response_CT(core, query);
+}
+
+
+static const char *qdra_link_route_treatment_CT(qd_parsed_field_t *field, qd_address_treatment_t *trt)
+{
+    if (field) {
+        qd_field_iterator_t *iter = qd_parse_raw(field);
+        if (qd_field_iterator_equal(iter, (unsigned char*) "linkBalanced")) {
+            *trt = QD_TREATMENT_LINK_BALANCED;
+            return 0;
+        }
+        return "Invalid value for 'distribution'";
+    }
+
+    *trt = QD_TREATMENT_LINK_BALANCED;
+    return 0;
+}
+
+
+static const char *qdra_link_route_direction_CT(qd_parsed_field_t *field, qd_direction_t *dir)
+{
+    if (field) {
+        qd_field_iterator_t *iter = qd_parse_raw(field);
+        if (qd_field_iterator_equal(iter, (unsigned char*) "in")) {
+            *dir = QD_INCOMING;
+            return 0;
+        } else if (qd_field_iterator_equal(iter, (unsigned char*) "out")) {
+            *dir = QD_OUTGOING;
+            return 0;
+        }
+        return "Invalid value for 'dir'";
+    }
+    return "Missing value for 'dir'";
+}
+
+
+static qdr_link_route_t *qdr_link_route_config_find_by_identity_CT(qdr_core_t *core, qd_field_iterator_t *identity)
+{
+    if (!identity)
+        return 0;
+
+    qdr_link_route_t *rc = DEQ_HEAD(core->link_routes);
+    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_link_route_t *qdr_link_route_config_find_by_name_CT(qdr_core_t *core, qd_field_iterator_t *name)
+{
+    if (!name)
+        return 0;
+
+    qdr_link_route_t *rc = DEQ_HEAD(core->link_routes);
+    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_link_route_delete_CT(qdr_core_t          *core,
+                                      qdr_query_t         *query,
+                                      qd_field_iterator_t *name,
+                                      qd_field_iterator_t *identity)
+{
+    qdr_link_route_t *lr = 0;
+
+    if (!name && !identity)
+        query->status = QD_AMQP_BAD_REQUEST;
+    else {
+        if (identity)
+            lr = qdr_link_route_config_find_by_identity_CT(core, identity);
+        else if (name)
+            lr = qdr_link_route_config_find_by_name_CT(core, name);
+
+        if (lr) {
+            qdr_route_del_link_route_CT(core, lr);
+            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_link_route_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_link_route_t *lr = DEQ_HEAD(core->link_routes);
+        while (lr) {
+            if (name && lr->name && qd_field_iterator_equal(name, (const unsigned char*) lr->name))
+                break;
+            lr = DEQ_NEXT(lr);
+        }
+
+        if (!!lr) {
+            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_link_route_columns[QDR_CONFIG_LINK_ROUTE_PREFIX]);
+        qd_parsed_field_t *distrib_field    = qd_parse_value_by_key(in_body, qdr_config_link_route_columns[QDR_CONFIG_LINK_ROUTE_DISTRIBUTION]);
+        qd_parsed_field_t *connection_field = qd_parse_value_by_key(in_body, qdr_config_link_route_columns[QDR_CONFIG_LINK_ROUTE_CONNECTION]);
+        qd_parsed_field_t *container_field  = qd_parse_value_by_key(in_body, qdr_config_link_route_columns[QDR_CONFIG_LINK_ROUTE_CONTAINER_ID]);
+        qd_parsed_field_t *dir_field        = qd_parse_value_by_key(in_body, qdr_config_link_route_columns[QDR_CONFIG_LINK_ROUTE_DIR]);
+
+        //
+        // Prefix and dir fields are mandatory.  Fail if they're not both here.
+        //
+        if (!prefix_field || !dir_field) {
+            query->status = QD_AMQP_BAD_REQUEST;
+            break;
+        }
+
+        qd_direction_t dir;
+        const char *error = qdra_link_route_direction_CT(dir_field, &dir);
+        if (error) {
+            query->status = QD_AMQP_BAD_REQUEST;
+            query->status.description = error;
+            break;
+        }
+
+        qd_address_treatment_t trt;
+        error = qdra_link_route_treatment_CT(distrib_field, &trt);
+        if (error) {
+            query->status = QD_AMQP_BAD_REQUEST;
+            query->status.description = error;
+            break;
+        }
+
+        //
+        // The request is good.  Create the entity.
+        //
+        bool               is_container = !!container_field;
+        qd_parsed_field_t *in_use_conn  = is_container ? container_field : connection_field;
+
+        qdr_route_add_link_route_CT(core, name, prefix_field, in_use_conn, is_container, trt, dir);
+
+        //
+        // Compose the result map for the response.
+        //
+        if (query->body) {
+            qd_compose_start_map(query->body);
+            for (int col = 0; col < QDR_CONFIG_LINK_ROUTE_COLUMN_COUNT; col++)
+                qdr_config_link_route_insert_column_CT(lr, 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 {
+        if (query->status.status / 100 > 2)
+            qd_log(core->log, QD_LOG_ERROR, "Error configuring linkRoute: %s", query->status.description);
+        free_qdr_query_t(query);
+    }
+}

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/56c5a93f/src/router_core/agent_config_link_route.h
----------------------------------------------------------------------
diff --git a/src/router_core/agent_config_link_route.h b/src/router_core/agent_config_link_route.h
new file mode 100644
index 0000000..b470de8
--- /dev/null
+++ b/src/router_core/agent_config_link_route.h
@@ -0,0 +1,35 @@
+#ifndef qdr_agent_config_link_route
+#define qdr_agent_config_link_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_config_link_route_get_first_CT(qdr_core_t *core, qdr_query_t *query, int offset);
+void qdra_config_link_route_get_next_CT(qdr_core_t *core, qdr_query_t *query);
+void qdra_config_link_route_create_CT(qdr_core_t *core, qd_field_iterator_t *name, qdr_query_t *query, qd_parsed_field_t *in_body);
+void qdra_config_link_route_update_CT(qdr_core_t *core, qdr_query_t *query, qd_parsed_field_t *in_body);
+void qdra_config_link_route_delete_CT(qdr_core_t *core, qdr_query_t *query, qd_field_iterator_t *name,
+                                qd_field_iterator_t *identity);
+
+#define QDR_CONFIG_LINK_ROUTE_COLUMN_COUNT 8
+
+const char *qdr_config_link_route_columns[QDR_CONFIG_LINK_ROUTE_COLUMN_COUNT + 1];
+
+#endif

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/56c5a93f/src/router_core/route_control.c
----------------------------------------------------------------------
diff --git a/src/router_core/route_control.c b/src/router_core/route_control.c
index 4e1c57c..a421802 100644
--- a/src/router_core/route_control.c
+++ b/src/router_core/route_control.c
@@ -156,10 +156,15 @@ void qdr_route_add_link_route_CT(qdr_core_t             *core,
         if (lr->conn_id->open_connection)
             qdr_link_route_activate_CT(core, lr, lr->conn_id->open_connection);
     }
+
+    //
+    // Add the link route to the core list
+    //
+    DEQ_INSERT_TAIL(core->link_routes, lr);
 }
 
 
-void qdr_route_del_link_route_CT(qdr_core_t *core)
+void qdr_route_del_link_route_CT(qdr_core_t *core, qdr_link_route_t *lr)
 {
 }
 

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/56c5a93f/src/router_core/route_control.h
----------------------------------------------------------------------
diff --git a/src/router_core/route_control.h b/src/router_core/route_control.h
index 5fe8202..f725a3d 100644
--- a/src/router_core/route_control.h
+++ b/src/router_core/route_control.h
@@ -29,7 +29,7 @@ void qdr_route_add_link_route_CT(qdr_core_t             *core,
                                  qd_address_treatment_t  treatment,
                                  qd_direction_t          dir);
 
-void qdr_route_del_link_route_CT(qdr_core_t *core);
+void qdr_route_del_link_route_CT(qdr_core_t *core, qdr_link_route_t *lr);
 
 void qdr_route_add_auto_link_CT(qdr_core_t             *core,
                                 qd_field_iterator_t    *name,


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