Repository: qpid-dispatch Updated Branches: refs/heads/master cf2431622 -> 76b28ae03
DISPATCH-570 - From Ganesh Murthy - Added general counters qdstat -g. This closes #114. Project: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/repo Commit: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/commit/76b28ae0 Tree: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/tree/76b28ae0 Diff: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/diff/76b28ae0 Branch: refs/heads/master Commit: 76b28ae0321d8a48e4f4befa318c91b18d5657fc Parents: cf24316 Author: Ted Ross <[email protected]> Authored: Wed Nov 23 13:45:13 2016 -0500 Committer: Ted Ross <[email protected]> Committed: Wed Nov 23 13:45:13 2016 -0500 ---------------------------------------------------------------------- include/qpid/dispatch/router_core.h | 1 + python/qpid_dispatch/management/qdrouter.json | 16 ++ src/CMakeLists.txt | 1 + src/router_core/agent.c | 15 +- src/router_core/agent_router.c | 196 +++++++++++++++++++++ src/router_core/agent_router.h | 32 ++++ src/router_core/management_agent.c | 3 + tests/system_tests_link_routes.py | 3 +- tests/system_tests_qdmanage.py | 10 ++ tests/system_tests_qdstat.py | 8 +- tools/qdstat | 8 +- 11 files changed, 289 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/76b28ae0/include/qpid/dispatch/router_core.h ---------------------------------------------------------------------- diff --git a/include/qpid/dispatch/router_core.h b/include/qpid/dispatch/router_core.h index 292c497..6755b35 100644 --- a/include/qpid/dispatch/router_core.h +++ b/include/qpid/dispatch/router_core.h @@ -572,6 +572,7 @@ typedef enum { QD_ROUTER_CONFIG_LINK_ROUTE, QD_ROUTER_CONFIG_AUTO_LINK, QD_ROUTER_CONNECTION, + QD_ROUTER_ROUTER, QD_ROUTER_LINK, QD_ROUTER_ADDRESS, QD_ROUTER_EXCHANGE, http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/76b28ae0/python/qpid_dispatch/management/qdrouter.json ---------------------------------------------------------------------- diff --git a/python/qpid_dispatch/management/qdrouter.json b/python/qpid_dispatch/management/qdrouter.json index 53b171d..39af630 100644 --- a/python/qpid_dispatch/management/qdrouter.json +++ b/python/qpid_dispatch/management/qdrouter.json @@ -438,6 +438,22 @@ "description":"Number of known peer router nodes.", "graph": true }, + "linkRouteCount": { + "type": "integer", + "description":"Number of link routes attached to the router node.", + "graph": true + }, + "autoLinkCount": { + "type": "integer", + "description":"Number of auto links attached to the router node.", + "graph": true + }, + "connectionCount": { + "type": "integer", + "description":"Number of open connections to the router node.", + "graph": true + }, + "workerThreads": { "type": "integer", "default": 4, http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/76b28ae0/src/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c5aa589..72f4d07 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -71,6 +71,7 @@ set(qpid_dispatch_SOURCES router_core/agent_config_auto_link.c router_core/agent_config_link_route.c router_core/agent_link.c + router_core/agent_router.c router_core/connections.c router_core/error.c router_core/forwarder.c http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/76b28ae0/src/router_core/agent.c ---------------------------------------------------------------------- diff --git a/src/router_core/agent.c b/src/router_core/agent.c index a96abb2..d61d478 100644 --- a/src/router_core/agent.c +++ b/src/router_core/agent.c @@ -23,6 +23,7 @@ #include "agent_config_auto_link.h" #include "agent_address.h" #include "agent_link.h" +#include "agent_router.h" #include "router_core_private.h" #include <stdio.h> @@ -188,6 +189,7 @@ qdr_query_t *qdr_manage_query(qdr_core_t *core, 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: qdr_agent_set_columns(query, attribute_names, qdr_config_auto_link_columns, QDR_CONFIG_AUTO_LINK_COLUMN_COUNT); break; case QD_ROUTER_CONNECTION: break; + case QD_ROUTER_ROUTER: qdr_agent_set_columns(query, attribute_names, qdr_router_columns, QDR_ROUTER_COLUMN_COUNT); 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_FORBIDDEN: break; @@ -206,6 +208,7 @@ void qdr_query_add_attribute_names(qdr_query_t *query) 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: qdr_agent_emit_columns(query, qdr_config_auto_link_columns, QDR_CONFIG_AUTO_LINK_COLUMN_COUNT); break; case QD_ROUTER_CONNECTION: break; + case QD_ROUTER_ROUTER: qdr_agent_emit_columns(query, qdr_router_columns, QDR_ROUTER_COLUMN_COUNT); 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_FORBIDDEN: qd_compose_empty_list(query->body); break; @@ -299,7 +302,11 @@ static void qdr_agent_set_columns(qdr_query_t *query, } } } - query->columns[idx+1] = -1; + if (count == 1 && idx == 1) + query->columns[idx] = -1; + else + query->columns[idx+1] = -1; + } @@ -342,6 +349,7 @@ static void qdr_manage_read_CT(qdr_core_t *core, qdr_action_t *action, bool disc case QD_ROUTER_CONFIG_LINK_ROUTE: qdra_config_link_route_get_CT(core, name, identity, query, qdr_config_link_route_columns); break; case QD_ROUTER_CONFIG_AUTO_LINK: qdra_config_auto_link_get_CT(core, name, identity, query, qdr_config_auto_link_columns); break; case QD_ROUTER_CONNECTION: break; + case QD_ROUTER_ROUTER: qdr_agent_forbidden(core, query, false); 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_FORBIDDEN: qdr_agent_forbidden(core, query, false); break; @@ -366,6 +374,7 @@ static void qdr_manage_create_CT(qdr_core_t *core, qdr_action_t *action, bool di case QD_ROUTER_CONFIG_LINK_ROUTE: qdra_config_link_route_create_CT(core, name, query, in_body); break; case QD_ROUTER_CONFIG_AUTO_LINK: qdra_config_auto_link_create_CT(core, name, query, in_body); break; case QD_ROUTER_CONNECTION: break; + case QD_ROUTER_ROUTER: qdr_agent_forbidden(core, query, false); break; case QD_ROUTER_LINK: break; case QD_ROUTER_ADDRESS: break; case QD_ROUTER_FORBIDDEN: qdr_agent_forbidden(core, query, false); break; @@ -391,6 +400,7 @@ static void qdr_manage_delete_CT(qdr_core_t *core, qdr_action_t *action, bool di case QD_ROUTER_CONFIG_LINK_ROUTE: qdra_config_link_route_delete_CT(core, query, name, identity); break; case QD_ROUTER_CONFIG_AUTO_LINK: qdra_config_auto_link_delete_CT(core, query, name, identity); break; case QD_ROUTER_CONNECTION: break; + case QD_ROUTER_ROUTER: qdr_agent_forbidden(core, query, false); break; case QD_ROUTER_LINK: break; case QD_ROUTER_ADDRESS: break; case QD_ROUTER_FORBIDDEN: qdr_agent_forbidden(core, query, false); break; @@ -414,6 +424,7 @@ static void qdr_manage_update_CT(qdr_core_t *core, qdr_action_t *action, bool di case QD_ROUTER_CONFIG_LINK_ROUTE: break; case QD_ROUTER_CONFIG_AUTO_LINK: break; case QD_ROUTER_CONNECTION: break; + case QD_ROUTER_ROUTER: break; case QD_ROUTER_LINK: qdra_link_update_CT(core, name, identity, query, in_body); break; case QD_ROUTER_ADDRESS: break; case QD_ROUTER_FORBIDDEN: qdr_agent_forbidden(core, query, false); break; @@ -440,6 +451,7 @@ static void qdrh_query_get_first_CT(qdr_core_t *core, qdr_action_t *action, bool case QD_ROUTER_CONFIG_LINK_ROUTE: qdra_config_link_route_get_first_CT(core, query, offset); break; case QD_ROUTER_CONFIG_AUTO_LINK: qdra_config_auto_link_get_first_CT(core, query, offset); break; case QD_ROUTER_CONNECTION: break; + case QD_ROUTER_ROUTER: qdra_router_get_first_CT(core, query, offset); 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_FORBIDDEN: qdr_agent_forbidden(core, query, true); break; @@ -460,6 +472,7 @@ static void qdrh_query_get_next_CT(qdr_core_t *core, qdr_action_t *action, bool case QD_ROUTER_CONFIG_LINK_ROUTE: qdra_config_link_route_get_next_CT(core, query); break; case QD_ROUTER_CONFIG_AUTO_LINK: qdra_config_auto_link_get_next_CT(core, query); break; case QD_ROUTER_CONNECTION: break; + case QD_ROUTER_ROUTER: qdra_router_get_next_CT(core, query); 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_FORBIDDEN: break; http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/76b28ae0/src/router_core/agent_router.c ---------------------------------------------------------------------- diff --git a/src/router_core/agent_router.c b/src/router_core/agent_router.c new file mode 100644 index 0000000..bb84711 --- /dev/null +++ b/src/router_core/agent_router.c @@ -0,0 +1,196 @@ +/* + * 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 "agent_router.h" +#include <inttypes.h> +#include <stdio.h> +#define QDR_ROUTER_NAME 0 +#define QDR_ROUTER_IDENTITY 1 +#define QDR_ROUTER_ID 2 +#define QDR_ROUTER_TYPE 3 +#define QDR_ROUTER_MODE 4 +#define QDR_ROUTER_AREA 5 +#define QDR_ROUTER_HELLO_INTERVAL 6 +#define QDR_ROUTER_HELLO_MAX_AGE 7 +#define QDR_ROUTER_RA_INTERVAL 8 +#define QDR_ROUTER_RA_INTERVAL_FLUX 9 +#define QDR_ROUTER_REMOTE_LS_MAX_AGE 10 +#define QDR_ROUTER_ADDR_COUNT 11 +#define QDR_ROUTER_LINK_COUNT 12 +#define QDR_ROUTER_NODE_COUNT 13 +#define QDR_ROUTER_LINK_ROUTE_COUNT 14 +#define QDR_ROUTER_AUTO_LINK_COUNT 15 +#define QDR_ROUTER_WORKER_THREADS 16 +#define QDR_ROUTER_DEBUG_DUMP 17 +#define QDR_ROUTER_SASL_CONFIG_PATH 18 +#define QDR_ROUTER_SASL_CONFIG_NAME 19 +#define QDR_ROUTER_ROUTER_ID 20 +#define QDR_ROUTER_MOBILE_ADDR_MAX_AGE 21 +#define QDR_ROUTER_CONNECTION_COUNT 22 + +const char *qdr_router_columns[] = + {"name", + "identity", + "id", + "type", + "mode", + "area", + "helloInterval", + "helloMaxAge", + "raInterval", + "raIntervalFlux", + "remoteLsMaxAge", + "addrCount", + "linkCount", + "nodeCount", + "linkRouteCount", + "autoLinkCount", // The connection id of the owner connection + "workerThreads", + "debugDump", + "saslConfigPath", + "saslConfigName", + "routerId", + "mobileAddrMaxAge", + "connectionCount", + 0}; + + +static const char *qd_router_mode_names[] = { + "standalone", + "interior", + "edge", + "endpoint" +}; + +static const char *router_mode(qd_router_mode_t router_mode) +{ + return qd_router_mode_names[(int)router_mode]; + +} + +static void qdr_agent_write_column_CT(qd_composed_field_t *body, int col, qdr_core_t *core) +{ + + switch(col) { + case QDR_ROUTER_IDENTITY: + // There is only one instance of router. Just give it an identity of 1 + qd_compose_insert_string(body, "1"); + break; + case QDR_ROUTER_TYPE: + qd_compose_insert_string(body, "org.apache.qpid.dispatch.router"); + break; + + case QDR_ROUTER_MODE: + qd_compose_insert_string(body, router_mode(core->router_mode)); + break; + + case QDR_ROUTER_AREA: + if (core->router_area) + qd_compose_insert_string(body, core->router_area); + else + qd_compose_insert_null(body); + break; + + case QDR_ROUTER_HELLO_INTERVAL: + qd_compose_insert_null(body); + break; + + case QDR_ROUTER_ADDR_COUNT: + qd_compose_insert_ulong(body, DEQ_SIZE(core->addrs)); + break; + + case QDR_ROUTER_LINK_COUNT: + qd_compose_insert_ulong(body, DEQ_SIZE(core->open_links)); + break; + + case QDR_ROUTER_NODE_COUNT: + qd_compose_insert_ulong(body, DEQ_SIZE(core->routers)); + break; + + case QDR_ROUTER_CONNECTION_COUNT: + qd_compose_insert_ulong(body, DEQ_SIZE(core->open_connections)); + break; + + case QDR_ROUTER_LINK_ROUTE_COUNT: + qd_compose_insert_ulong(body, DEQ_SIZE(core->link_routes)); + break; + + case QDR_ROUTER_AUTO_LINK_COUNT: + qd_compose_insert_ulong(body, DEQ_SIZE(core->auto_links)); + break; + + case QDR_ROUTER_ROUTER_ID: + case QDR_ROUTER_ID: + case QDR_ROUTER_NAME: + if (core->router_id) + qd_compose_insert_string(body, core->router_id); + else + qd_compose_insert_null(body); + break; + + default: + qd_compose_insert_null(body); + break; + } +} + + + +static void qdr_agent_write_router_CT(qdr_query_t *query, qdr_core_t *core) +{ + qd_composed_field_t *body = query->body; + + qd_compose_start_list(body); + int i = 0; + while (query->columns[i] >= 0) { + qdr_agent_write_column_CT(body, query->columns[i], core); + i++; + } + qd_compose_end_list(body); +} + +void qdra_router_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 (offset >= 1) { + query->more = false; + qdr_agent_enqueue_response_CT(core, query); + return; + } + + // + // Write the columns of core into the response body. + // + qdr_agent_write_router_CT(query, core); + + // + // Enqueue the response. + // + qdr_agent_enqueue_response_CT(core, query); +} + +// Nothing to do here. The router has only one entry. +void qdra_router_get_next_CT(qdr_core_t *core, qdr_query_t *query) +{ + +} http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/76b28ae0/src/router_core/agent_router.h ---------------------------------------------------------------------- diff --git a/src/router_core/agent_router.h b/src/router_core/agent_router.h new file mode 100644 index 0000000..b2738f3 --- /dev/null +++ b/src/router_core/agent_router.h @@ -0,0 +1,32 @@ +#ifndef qdr_agent_router +#define qdr_agent_router 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" + +#define QDR_ROUTER_COLUMN_COUNT 23 + +const char *qdr_router_columns[QDR_ROUTER_COLUMN_COUNT + 1]; + +void qdra_router_get_first_CT(qdr_core_t *core, qdr_query_t *query, int offset); +void qdra_router_get_next_CT(qdr_core_t *core, qdr_query_t *query); +void qdra_router_get_next_CT(qdr_core_t *core, qdr_query_t *query); + +#endif http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/76b28ae0/src/router_core/management_agent.c ---------------------------------------------------------------------- diff --git a/src/router_core/management_agent.c b/src/router_core/management_agent.c index 9fb6503..455337b 100644 --- a/src/router_core/management_agent.c +++ b/src/router_core/management_agent.c @@ -46,6 +46,7 @@ const unsigned char *auto_link_entity_type = (unsigned char*) "org.apache.q 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 *console_entity_type = (unsigned char*) "org.apache.qpid.dispatch.console"; +const unsigned char *router_entity_type = (unsigned char*) "org.apache.qpid.dispatch.router"; const char * const status_description = "statusDescription"; const char * const correlation_id = "correlation-id"; @@ -405,6 +406,8 @@ static bool qd_can_handle_request(qd_parsed_field_t *properties_fld, *entity_type = QD_ROUTER_CONFIG_LINK_ROUTE; else if (qd_iterator_equal(qd_parse_raw(parsed_field), auto_link_entity_type)) *entity_type = QD_ROUTER_CONFIG_AUTO_LINK; + else if (qd_iterator_equal(qd_parse_raw(parsed_field), router_entity_type)) + *entity_type = QD_ROUTER_ROUTER; else if (qd_iterator_equal(qd_parse_raw(parsed_field), console_entity_type)) *entity_type = QD_ROUTER_FORBIDDEN; else http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/76b28ae0/tests/system_tests_link_routes.py ---------------------------------------------------------------------- diff --git a/tests/system_tests_link_routes.py b/tests/system_tests_link_routes.py index a70f59c..fd7a673 100644 --- a/tests/system_tests_link_routes.py +++ b/tests/system_tests_link_routes.py @@ -252,8 +252,9 @@ class LinkRouteTest(TestCase): # Connect to the router acting like the broker (QDR.A) and check the deliveriesIngress and deliveriesEgress local_node = Node.connect(self.routers[0].addresses[0], timeout=TIMEOUT) + self.assertEqual(u'QDR.A', local_node.query(type='org.apache.qpid.dispatch.router', - attribute_names=['id']).results[0][0]) + attribute_names=[u'id']).results[0][0]) self.assertEqual(1, local_node.read(type='org.apache.qpid.dispatch.router.address', name='M0org.apache.dev').deliveriesEgress) http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/76b28ae0/tests/system_tests_qdmanage.py ---------------------------------------------------------------------- diff --git a/tests/system_tests_qdmanage.py b/tests/system_tests_qdmanage.py index 0c70e66..395d874 100644 --- a/tests/system_tests_qdmanage.py +++ b/tests/system_tests_qdmanage.py @@ -489,5 +489,15 @@ class QdmanageTestSsl(QdmanageTest): delete_command = 'DELETE --type=sslProfile --name=' + ssl_profile_name self.run_qdmanage(delete_command) + def test_zzz_router_query(self): + long_type = 'org.apache.qpid.dispatch.router' + query_command = 'QUERY --type=' + long_type + output = json.loads(self.run_qdmanage(query_command)) + self.assertEqual(3, output[0]['connectionCount']) + self.assertEqual(1, output[0]['linkRouteCount']) + self.assertEqual(1, output[0]['autoLinkCount']) + self.assertEqual('interior', output[0]['mode']) + self.assertEqual('org.apache.qpid.dispatch.router', output[0]['type']) + if __name__ == '__main__': unittest.main(main_module()) http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/76b28ae0/tests/system_tests_qdstat.py ---------------------------------------------------------------------- diff --git a/tests/system_tests_qdstat.py b/tests/system_tests_qdstat.py index 45b5ab6..016acae 100644 --- a/tests/system_tests_qdstat.py +++ b/tests/system_tests_qdstat.py @@ -50,7 +50,13 @@ class QdstatTest(system_test.TestCase): self.run_qdstat(['--help'], r'Usage: qdstat') def test_general(self): - self.run_qdstat(['--general'], r'(?s)Router Statistics.*Mode\s*Standalone') + out = self.run_qdstat(['--general'], r'(?s)Router Statistics.*Mode\s*Standalone') + self.assertTrue("Connections 1" in out) + self.assertTrue("Nodes 0" in out) + self.assertTrue("Auto Links 0" in out) + self.assertTrue("Link Routes 0" in out) + self.assertTrue("Router Id QDR.A" in out) + self.assertTrue("Mode standalone" in out) def test_connections(self): self.run_qdstat(['--connections'], r'host.*container.*role') http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/76b28ae0/tools/qdstat ---------------------------------------------------------------------- diff --git a/tools/qdstat b/tools/qdstat index ee9f6b1..546c243 100755 --- a/tools/qdstat +++ b/tools/qdstat @@ -212,7 +212,13 @@ class BusManager(Node): router = objects[0] rows.append(('Mode', router.mode)) rows.append(('Area', router.area)) - rows.append(('Router Id', self._identity_clean(router.identity, router.routerId))) + rows.append(('Router Id', router.routerId)) + rows.append(('Link Routes', router.linkRouteCount)) + rows.append(('Auto Links', router.autoLinkCount)) + rows.append(('Links', router.linkCount)) + rows.append(('Nodes', router.nodeCount)) + rows.append(('Addresses', router.addrCount)) + rows.append(('Connections', router.connectionCount)) title = "Router Statistics" dispRows = rows --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
