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]
