Repository: qpid-dispatch
Updated Branches:
  refs/heads/master 4c5330a30 -> 06296ba31


DISPATCH-211 - Exposed connection properties in management response


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

Branch: refs/heads/master
Commit: 06296ba31b9a69a7748adfda8d453f89fee8c843
Parents: 4c5330a
Author: Ganesh Murthy <[email protected]>
Authored: Fri Jun 10 10:38:10 2016 -0400
Committer: Ganesh Murthy <[email protected]>
Committed: Fri Jun 10 10:38:10 2016 -0400

----------------------------------------------------------------------
 .../qpid_dispatch_internal/management/schema.py |  1 +
 src/entity.c                                    | 32 +++++++++++
 src/entity.h                                    | 15 +++++
 src/server.c                                    | 60 ++++++++++++++++++++
 tests/system_tests_one_router.py                | 19 ++++++-
 5 files changed, 126 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/06296ba3/python/qpid_dispatch_internal/management/schema.py
----------------------------------------------------------------------
diff --git a/python/qpid_dispatch_internal/management/schema.py 
b/python/qpid_dispatch_internal/management/schema.py
index 5fe6a75..fe81ffb 100644
--- a/python/qpid_dispatch_internal/management/schema.py
+++ b/python/qpid_dispatch_internal/management/schema.py
@@ -156,6 +156,7 @@ BUILTIN_TYPES = OrderedDict(
                           Type("integer", int),
                           Type("list", list),
                           Type("map", dict),
+                          Type("dict", dict),
                           BooleanType()])
 
 def get_type(rep):

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/06296ba3/src/entity.c
----------------------------------------------------------------------
diff --git a/src/entity.c b/src/entity.c
index e290480..065dd74 100644
--- a/src/entity.c
+++ b/src/entity.c
@@ -162,6 +162,38 @@ qd_error_t qd_entity_set_list(qd_entity_t *entity, const 
char *attribute) {
     return qd_entity_set_py(entity, attribute, PyList_New(0));
 }
 
+
+qd_error_t qd_entity_set_map(qd_entity_t *entity, const char *attribute) {
+    //CHECK(qd_entity_clear(entity, attribute));
+    return qd_entity_set_py(entity, attribute, PyDict_New());
+}
+
+qd_error_t qd_entity_set_map_key_value(qd_entity_t *entity, const char 
*attribute, const char *key, const char *value)
+{
+    PyObject *py_key = PyString_FromString(key);
+    PyObject *py_value = PyString_FromString(value);
+    PyObject *py_attribute = PyString_FromString(attribute);
+
+    qd_error_t ret = QD_ERROR_NONE;
+
+    if (PyDict_Contains((PyObject*)entity, py_attribute) == 1) {
+        PyObject* dict = PyDict_GetItem((PyObject*)entity, py_attribute);
+        if (PyDict_SetItem(dict, py_key, py_value) < 0)
+            ret = QD_ERROR_PYTHON;
+    }
+    else
+        ret = QD_ERROR_VALUE;
+
+    Py_XDECREF(py_key);
+    Py_XDECREF(py_value);
+    Py_XDECREF(py_attribute);
+
+    return ret;
+}
+
+
+
+
 qd_error_t qd_entity_set_stringf(qd_entity_t *entity, const char* attribute, 
const char *format, ...)
 {
     // Calculate the size

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/06296ba3/src/entity.h
----------------------------------------------------------------------
diff --git a/src/entity.h b/src/entity.h
index 894938a..0b54c2c 100644
--- a/src/entity.h
+++ b/src/entity.h
@@ -96,6 +96,21 @@ qd_error_t qd_entity_clear(qd_entity_t *entity, const char 
*attribute);
  */
 qd_error_t qd_entity_set_list(qd_entity_t *entity, const char *attribute);
 
+
+/**
+ * Set the attribute to an empty dictionary. To further add key/value pairs to 
this new dict, use qd_entity_set_map_key_value
+ */
+qd_error_t qd_entity_set_map(qd_entity_t *entity, const char *attribute);
+
+/**
+ * Add a new key/value pair to the attribute which needs to be dict.
+ * @return - QD_ERROR_NONE if there were no errors
+ *         - QD_ERROR_PYTHON if there was an error from the Python side when 
setting the key/value error
+ *         - QD_ERROR_VALUE if a non-dictionary attribute was specified
+ */
+qd_error_t qd_entity_set_map_key_value(qd_entity_t *entity, const char 
*attribute, const char *key, const char *value);
+
+
 /// @}
 
 #endif

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/06296ba3/src/server.c
----------------------------------------------------------------------
diff --git a/src/server.c b/src/server.c
index d3dd489..f9bec0b 100644
--- a/src/server.c
+++ b/src/server.c
@@ -17,6 +17,7 @@
  * under the License.
  */
 
+#include <Python.h>
 #include <qpid/dispatch/ctools.h>
 #include <qpid/dispatch/threading.h>
 #include <qpid/dispatch/log.h>
@@ -335,6 +336,64 @@ void qd_connection_set_user(qd_connection_t *conn)
         conn->user_id = DEFAULT_USER_ID;
 }
 
+
+static void qd_get_next_pn_data(pn_data_t *data, const char **d)
+{
+    if (pn_data_next(data)) {
+        switch (pn_data_type(data)) {
+            case PN_STRING:
+                *d = pn_data_get_string(data).start;
+                break;
+            case PN_SYMBOL:
+                *d = pn_data_get_symbol(data).start;
+                break;
+            default:
+                break;
+        }
+    }
+}
+
+
+/**
+ * Obtains the remote connection properties and sets it as a map on the passed 
in entity.
+ * @param
+ */
+static qd_error_t qd_set_connection_properties(qd_entity_t* entity, 
qd_connection_t *conn)
+{
+    // Get the connection properties and stick it into the entity as a map
+    pn_data_t *data = pn_connection_remote_properties(conn->pn_conn);
+    const char *props = "properties";
+    if (data) {
+        size_t count = pn_data_get_map(data);
+        pn_data_enter(data);
+
+        // Create a new map.
+        qd_error_t error_t = qd_entity_set_map(entity, props);
+
+        if (error_t != QD_ERROR_NONE)
+            return error_t;
+
+        for (size_t i = 0; i < count/2; i++) {
+            const char *key   = 0;
+            qd_get_next_pn_data(data, &key);
+            const char *value = 0;
+            qd_get_next_pn_data(data, &value);
+
+            // Now we have a key and value
+            error_t = qd_entity_set_map_key_value(entity, props, key, value);
+
+            if (error_t != QD_ERROR_NONE)
+                return error_t;
+        }
+        pn_data_exit(data);
+    }
+
+    return QD_ERROR_NONE;
+}
+
+
+
+
 qd_error_t qd_entity_refresh_connection(qd_entity_t* entity, void *impl)
 {
     qd_connection_t *conn = (qd_connection_t*)impl;
@@ -368,6 +427,7 @@ qd_error_t qd_entity_refresh_connection(qd_entity_t* 
entity, void *impl)
         qd_entity_set_string(entity, "role", config->role) == 0 &&
         qd_entity_set_string(entity, "dir", conn->connector ? "out" : "in") == 
0 &&
         qd_entity_set_string(entity, "user", user) == 0 &&
+        qd_set_connection_properties(entity, conn) == 0 &&
         qd_entity_set_long(entity, "identity", conn->connection_id) == 0 &&
         qd_entity_set_bool(entity, "isAuthenticated", tport && 
pn_transport_is_authenticated(tport)) == 0 &&
         qd_entity_set_bool(entity, "isEncrypted", tport && 
pn_transport_is_encrypted(tport)) == 0 &&

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/06296ba3/tests/system_tests_one_router.py
----------------------------------------------------------------------
diff --git a/tests/system_tests_one_router.py b/tests/system_tests_one_router.py
index 130c05a..6b6dd6c 100644
--- a/tests/system_tests_one_router.py
+++ b/tests/system_tests_one_router.py
@@ -22,11 +22,13 @@ from proton import Message, Delivery, PENDING, ACCEPTED, 
REJECTED
 from system_test import TestCase, Qdrouterd, main_module
 from proton.handlers import MessagingHandler
 from proton.reactor import Container, AtMostOnce, AtLeastOnce
+from proton.utils import BlockingConnection, SyncRequestResponse
+from qpid_dispatch.management.client import Node
 
+CONNECTION_PROPERTIES={u'connection': u'properties'}
 
 class RouterTest(TestCase):
     """System tests involving a single router"""
-
     @classmethod
     def setUpClass(cls):
         """Start a router and a messenger"""
@@ -1069,6 +1071,21 @@ class RouterTest(TestCase):
         test.run()
         self.assertEqual(None, test.error)
 
+    def test_connection_properties(self):
+        connection = BlockingConnection(self.router.addresses[0],
+                                        timeout=60,
+                                        properties=CONNECTION_PROPERTIES)
+        client = SyncRequestResponse(connection)
+
+        node = Node.connect(self.router.addresses[0])
+
+        results = [[{u'connection': u'properties'}], [{}]]
+
+        
self.assertEqual(node.query(type='org.apache.qpid.dispatch.connection', 
attribute_names=['properties']).results,
+                         results)
+
+        client.connection.close()
+
 
 class Timeout(object):
     def __init__(self, parent):


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

Reply via email to