summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Ross <tross@apache.org>2013-06-11 14:13:11 +0000
committerTed Ross <tross@apache.org>2013-06-11 14:13:11 +0000
commitac14f3c7b68424250a32f62c2f3008778cfe902e (patch)
tree460e5ed1dcc2f36b2498936bcf0680c0fc3f6983
parent2da54e759e2a1f04bd0c21f116a44b4e3944ba89 (diff)
downloadqpid-python-ac14f3c7b68424250a32f62c2f3008778cfe902e.tar.gz
QPID_4913 - Work in progress
- Added configuration handling of listeners (basic, still needs ssl, sasl, etc.) - Updated the server tests to use the configuration file rather than hard-coded settings. - Fixed a bug in the CMake file regarding the use of the PYTHON include path. - Made changes to accomodate older compilers. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@1491805 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--extras/dispatch/CMakeLists.txt2
-rw-r--r--extras/dispatch/etc/qpid-dispatch.conf117
-rw-r--r--extras/dispatch/include/qpid/dispatch/dispatch.h5
-rw-r--r--extras/dispatch/include/qpid/dispatch/server.h18
-rw-r--r--extras/dispatch/router/src/main.c24
-rw-r--r--extras/dispatch/src/config.c17
-rw-r--r--extras/dispatch/src/config_private.h2
-rw-r--r--extras/dispatch/src/dispatch.c70
-rw-r--r--extras/dispatch/src/dispatch_private.h2
-rw-r--r--extras/dispatch/tests/CMakeLists.txt2
-rw-r--r--extras/dispatch/tests/run_unit_tests.c8
-rw-r--r--extras/dispatch/tests/server_test.c11
-rw-r--r--extras/dispatch/tests/threads4.conf26
13 files changed, 208 insertions, 96 deletions
diff --git a/extras/dispatch/CMakeLists.txt b/extras/dispatch/CMakeLists.txt
index d01e6c1321..f51d25c486 100644
--- a/extras/dispatch/CMakeLists.txt
+++ b/extras/dispatch/CMakeLists.txt
@@ -56,7 +56,7 @@ include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}/src
${proton_include}
- ${PYTHON_INCLUDE_DIRS}
+ ${PYTHON_INCLUDE_PATH}
)
##
diff --git a/extras/dispatch/etc/qpid-dispatch.conf b/extras/dispatch/etc/qpid-dispatch.conf
index d9dee9edf4..81e4f8f617 100644
--- a/extras/dispatch/etc/qpid-dispatch.conf
+++ b/extras/dispatch/etc/qpid-dispatch.conf
@@ -27,7 +27,7 @@ container {
## process message traffic and other application work (timers, non-amqp
## file descriptors, etc.)
##
- ## The number of threads should be a function of the available
+ ## The number of threads should be related to the number of available
## processor cores. To fully utilize a quad-core system, set the
## number of threads to 4.
##
@@ -42,6 +42,84 @@ container {
container-name: Qpid.Dispatch.Router.A
}
+
+##
+## SSL Profile section - Zero or more SSL profiles may be defined here and
+## then referenced later in listeners (for incoming connections) or
+## connectors (for outgoing connectors).
+##
+ssl-profile {
+ ##
+ ## name - The name of the profile to be referenced later.
+ ##
+ name: ssl-profile-name
+
+ ##
+ ## trusted-cert-db - The path to the database that contains the public
+ ## certificates of trusted certificate authorities (CAs).
+ ##
+ ## trusted-cert-db: /path/to/trusted-ca.db
+
+ ##
+ ## cert-file - The path to the file containing the PEM-formatted public
+ ## certificate to be used on the local end of any connections using
+ ## this profile.
+ ##
+ ## cert-file: /path/to/cert-file.pem
+
+ ##
+ ## key-file - The path to the file containing the PEM-formatted private
+ ## key for the above certificate.
+ ##
+ ## key-file: /path/to/private-key-file.pem
+
+ ##
+ ## password-file - If the above private key is password protected, this
+ ## is the path to a file containing the password that unlocks the
+ ## certificate key.
+ ##
+ ## password-file: /path/to/password-file
+
+ ##
+ ## password - An alternative to storing the password in a file
+ ## referenced by password-file is to supply the password right here in
+ ## the configuration file. This option can be used by supplying the
+ ## password in the 'password' option. Don't use both password and
+ ## password-file in the same profile.
+ ##
+ ## password: <password>
+}
+
+
+##
+## Listeners and Connectors
+##
+listener {
+ addr: 0.0.0.0
+ port: 5672
+ sasl-mechanisms: ANONYMOUS
+}
+
+listener {
+ label: Router Interconnect Access
+ addr: 0.0.0.0
+ port: 5671
+ sasl-mechanisms: EXTERNAL
+ ssl-profile: ssl-profile-name
+ require-peer-auth: yes
+ allow-unsecured: no
+}
+
+connector {
+ label: Router Uplink
+ host: backbone.enterprise.com
+ port: 5671
+ sasl-mechanisms: EXTERNAL
+ ssl-profile: ssl-profile-name
+ allow-redirect: no
+}
+
+
##
## Router section - Configure the AMQP router function.
##
@@ -92,41 +170,4 @@ router {
mobile-addr-max-age: 60
}
-ssl-profile {
- name: ssl-link
- trusted-cert-db: /opt/dispatch/x.509/cert.db
- cert-file: /opt/dispatch/x.509/router-cert.pem
- key-file: /opt/dispatch/x.509/router-key.pem
- password-file: /opt/dispatch/x.509/router-key.pass
-}
-
-
-##
-## Listeners and Connectors
-##
-listener {
- addr: 0.0.0.0
- port: 5672
- sasl-mechanisms: ANONYMOUS
-}
-
-listener {
- label: Router Interconnect Access
- addr: 0.0.0.0
- port: 5671
- sasl-mechanisms: EXTERNAL
- ssl-profile: ssl-link
- require-peer-auth: yes
- allow-unsecured: no
-}
-
-connector {
- label: Router Uplink
- host: backbone.enterprise.com
- port: 5671
- sasl-mechanisms: EXTERNAL
- ssl-profile: ssl-link
- allow-redirect: no
-}
-
diff --git a/extras/dispatch/include/qpid/dispatch/dispatch.h b/extras/dispatch/include/qpid/dispatch/dispatch.h
index e785cb6385..87f3fc32d1 100644
--- a/extras/dispatch/include/qpid/dispatch/dispatch.h
+++ b/extras/dispatch/include/qpid/dispatch/dispatch.h
@@ -29,9 +29,10 @@ typedef struct dx_dispatch_t dx_dispatch_t;
/**
* \brief Initialize the Dispatch library and prepare it for operation.
*
+ * #param config_path The path to the configuration file.
* @return A handle to be used in API calls for this instance.
*/
-dx_dispatch_t *dx_dispatch();
+dx_dispatch_t *dx_dispatch(const char *config_path);
/**
@@ -41,6 +42,8 @@ dx_dispatch_t *dx_dispatch();
*/
void dx_dispatch_free(dx_dispatch_t *dispatch);
+void dx_dispatch_configure(dx_dispatch_t *dispatch);
+
/**
* @}
diff --git a/extras/dispatch/include/qpid/dispatch/server.h b/extras/dispatch/include/qpid/dispatch/server.h
index 7e2c56a7dc..7b2d4a2432 100644
--- a/extras/dispatch/include/qpid/dispatch/server.h
+++ b/extras/dispatch/include/qpid/dispatch/server.h
@@ -283,29 +283,29 @@ typedef struct dx_server_config_t {
/**
* Host name or network address to bind to a listener or use in the connector.
*/
- char *host;
+ const char *host;
/**
* Port name or number to bind to a listener or use in the connector.
*/
- char *port;
+ const char *port;
/**
* Space-separated list of SASL mechanisms to be accepted for the connection.
*/
- char *sasl_mechanisms;
+ const char *sasl_mechanisms;
/**
* If appropriate for the mechanism, the username for authentication
* (connector only)
*/
- char *sasl_username;
+ const char *sasl_username;
/**
* If appropriate for the mechanism, the password for authentication
* (connector only)
*/
- char *sasl_password;
+ const char *sasl_password;
/**
* If appropriate for the mechanism, the minimum acceptable security strength factor
@@ -338,23 +338,23 @@ typedef struct dx_server_config_t {
* Path to the file containing the PEM-formatted public certificate for the local end
* of the connection.
*/
- char *ssl_certificate_file;
+ const char *ssl_certificate_file;
/**
* Path to the file containing the PEM-formatted private key for the local end of the
* connection.
*/
- char *ssl_private_key_file;
+ const char *ssl_private_key_file;
/**
* The password used to sign the private key, or NULL if the key is not protected.
*/
- char *ssl_password;
+ const char *ssl_password;
/**
* Path to the file containing the PEM-formatted set of certificates of trusted CAs.
*/
- char *ssl_trusted_certificate_db;
+ const char *ssl_trusted_certificate_db;
/**
* Iff non-zero, require that the peer's certificate be supplied and that it be authentic
diff --git a/extras/dispatch/router/src/main.c b/extras/dispatch/router/src/main.c
index d97895208f..20c821d04f 100644
--- a/extras/dispatch/router/src/main.c
+++ b/extras/dispatch/router/src/main.c
@@ -76,28 +76,8 @@ static void server_signal_handler(void* context, int signum)
static void startup(void *context)
{
- // TODO - Move this into a configuration framework
-
dx_server_pause(dispatch);
-
- static dx_server_config_t server_config;
- server_config.host = "0.0.0.0";
- server_config.port = "5672";
- server_config.sasl_mechanisms = "ANONYMOUS";
- server_config.ssl_enabled = 0;
-
- dx_server_listen(dispatch, &server_config, 0);
-
- /*
- static dx_server_config_t client_config;
- client_config.host = "0.0.0.0";
- client_config.port = "10000";
- client_config.sasl_mechanisms = "ANONYMOUS";
- client_config.ssl_enabled = 0;
-
- dx_server_connect(dispatch, &client_config, 0);
- */
-
+ dx_dispatch_configure(dispatch);
dx_server_resume(dispatch);
}
@@ -106,7 +86,7 @@ int main(int argc, char **argv)
{
dx_log_set_mask(LOG_INFO | LOG_TRACE | LOG_ERROR);
- dispatch = dx_dispatch();
+ dispatch = dx_dispatch("../etc/qpid-dispatch.conf");
dx_server_set_signal_handler(dispatch, server_signal_handler, 0);
dx_server_set_start_handler(dispatch, thread_start_handler, 0);
diff --git a/extras/dispatch/src/config.c b/extras/dispatch/src/config.c
index bc99d7f91c..407f2ffb4b 100644
--- a/extras/dispatch/src/config.c
+++ b/extras/dispatch/src/config.c
@@ -47,7 +47,7 @@ void dx_config_finalize()
}
-dx_config_t *dx_config(char *filename)
+dx_config_t *dx_config(const char *filename)
{
dx_config_t *config = new_dx_config_t();
@@ -116,8 +116,9 @@ int dx_config_item_count(const dx_config_t *config, const char *section)
pMethod = PyObject_GetAttrString(config->pObject, "item_count");
if (!pMethod || !PyCallable_Check(pMethod)) {
dx_log(log_module, LOG_ERROR, "Problem with configuration module: No callable 'item_count'");
- if (pMethod)
+ if (pMethod) {
Py_DECREF(pMethod);
+ }
return 0;
}
@@ -128,8 +129,9 @@ int dx_config_item_count(const dx_config_t *config, const char *section)
Py_DECREF(pArgs);
if (pResult && PyInt_Check(pResult))
result = (int) PyInt_AsLong(pResult);
- if (pResult)
+ if (pResult) {
Py_DECREF(pResult);
+ }
Py_DECREF(pMethod);
return result;
@@ -148,8 +150,9 @@ static PyObject *item_value(const dx_config_t *config, const char *section, int
pMethod = PyObject_GetAttrString(config->pObject, method);
if (!pMethod || !PyCallable_Check(pMethod)) {
dx_log(log_module, LOG_ERROR, "Problem with configuration module: No callable '%s'", method);
- if (pMethod)
+ if (pMethod) {
Py_DECREF(pMethod);
+ }
return 0;
}
@@ -179,8 +182,9 @@ const char *dx_config_item_value_string(const dx_config_t *config, const char *s
strncpy(value, PyString_AsString(pResult), size + 1);
}
- if (pResult)
+ if (pResult) {
Py_DECREF(pResult);
+ }
return value;
}
@@ -194,8 +198,9 @@ uint32_t dx_config_item_value_int(const dx_config_t *config, const char *section
if (pResult && PyLong_Check(pResult))
value = (uint32_t) PyLong_AsLong(pResult);
- if (pResult)
+ if (pResult) {
Py_DECREF(pResult);
+ }
return value;
}
diff --git a/extras/dispatch/src/config_private.h b/extras/dispatch/src/config_private.h
index bb114ebde0..3c95f6451f 100644
--- a/extras/dispatch/src/config_private.h
+++ b/extras/dispatch/src/config_private.h
@@ -23,7 +23,7 @@
void dx_config_initialize();
void dx_config_finalize();
-dx_config_t *dx_config(char *filename);
+dx_config_t *dx_config(const char *filename);
void dx_config_free(dx_config_t *config);
#endif
diff --git a/extras/dispatch/src/dispatch.c b/extras/dispatch/src/dispatch.c
index 3c8fa9ba83..23199c7c99 100644
--- a/extras/dispatch/src/dispatch.c
+++ b/extras/dispatch/src/dispatch.c
@@ -19,10 +19,11 @@
#include "python_embedded.h"
#include <qpid/dispatch.h>
+#include <qpid/dispatch/server.h>
+#include <qpid/dispatch/ctools.h>
#include "dispatch_private.h"
#include "alloc_private.h"
#include "log_private.h"
-#include "config_private.h"
/**
* Private Function Prototypes
@@ -42,9 +43,24 @@ void dx_agent_free(dx_agent_t *agent);
static const char *CONF_CONTAINER = "container";
static const char *CONF_ROUTER = "router";
+static const char *CONF_LISTENER = "listener";
-dx_dispatch_t *dx_dispatch()
+typedef struct dx_config_listener_t {
+ DEQ_LINKS(struct dx_config_listener_t);
+ dx_server_config_t configuration;
+ dx_listener_t *listener;
+} dx_config_listener_t;
+
+
+ALLOC_DECLARE(dx_config_listener_t);
+ALLOC_DEFINE(dx_config_listener_t);
+DEQ_DECLARE(dx_config_listener_t, listener_list_t);
+
+listener_list_t listeners;
+
+
+dx_dispatch_t *dx_dispatch(const char *config_path)
{
dx_dispatch_t *dx = NEW(dx_dispatch_t);
@@ -57,20 +73,22 @@ dx_dispatch_t *dx_dispatch()
dx_log_initialize();
dx_alloc_initialize();
+ DEQ_INIT(listeners);
+
dx_config_initialize();
- dx_config_t *config = dx_config("../etc/qpid-dispatch.conf");
+ dx->config = dx_config(config_path);
- if (config) {
- int count = dx_config_item_count(config, CONF_CONTAINER);
+ if (dx->config) {
+ int count = dx_config_item_count(dx->config, CONF_CONTAINER);
if (count == 1) {
- thread_count = dx_config_item_value_int(config, CONF_CONTAINER, 0, "worker-threads");
- container_name = dx_config_item_value_string(config, CONF_CONTAINER, 0, "container-name");
+ thread_count = dx_config_item_value_int(dx->config, CONF_CONTAINER, 0, "worker-threads");
+ container_name = dx_config_item_value_string(dx->config, CONF_CONTAINER, 0, "container-name");
}
- count = dx_config_item_count(config, CONF_ROUTER);
+ count = dx_config_item_count(dx->config, CONF_ROUTER);
if (count == 1) {
- router_area = dx_config_item_value_string(config, CONF_ROUTER, 0, "area");
- router_id = dx_config_item_value_string(config, CONF_ROUTER, 0, "router-id");
+ router_area = dx_config_item_value_string(dx->config, CONF_ROUTER, 0, "area");
+ router_id = dx_config_item_value_string(dx->config, CONF_ROUTER, 0, "router-id");
}
}
@@ -95,14 +113,13 @@ dx_dispatch_t *dx_dispatch()
dx_container_setup_agent(dx);
dx_router_setup_agent(dx);
- dx_config_free(config);
-
return dx;
}
void dx_dispatch_free(dx_dispatch_t *dx)
{
+ dx_config_free(dx->config);
dx_config_finalize();
dx_agent_free(dx->agent);
dx_router_free(dx->router);
@@ -112,3 +129,32 @@ void dx_dispatch_free(dx_dispatch_t *dx)
dx_python_finalize();
}
+
+static void configure_connections(dx_dispatch_t *dx)
+{
+ int count;
+
+ if (!dx->config)
+ return;
+
+ count = dx_config_item_count(dx->config, CONF_LISTENER);
+ for (int i = 0; i < count; i++) {
+ dx_config_listener_t *l = new_dx_config_listener_t();
+ memset(l, 0, sizeof(dx_config_listener_t));
+
+ l->configuration.host = dx_config_item_value_string(dx->config, CONF_LISTENER, i, "addr");
+ l->configuration.port = dx_config_item_value_string(dx->config, CONF_LISTENER, i, "port");
+ l->configuration.sasl_mechanisms =
+ dx_config_item_value_string(dx->config, CONF_LISTENER, i, "sasl-mechansism");
+ l->configuration.ssl_enabled = 0;
+
+ l->listener = dx_server_listen(dx, &l->configuration, l);
+ }
+}
+
+
+void dx_dispatch_configure(dx_dispatch_t *dx)
+{
+ configure_connections(dx);
+}
+
diff --git a/extras/dispatch/src/dispatch_private.h b/extras/dispatch/src/dispatch_private.h
index 699e3a2be4..ef93441776 100644
--- a/extras/dispatch/src/dispatch_private.h
+++ b/extras/dispatch/src/dispatch_private.h
@@ -20,6 +20,7 @@
*/
#include "server_private.h"
+#include "config_private.h"
typedef struct dx_container_t dx_container_t;
typedef struct dx_router_t dx_router_t;
@@ -30,6 +31,7 @@ struct dx_dispatch_t {
dx_container_t *container;
dx_router_t *router;
dx_agent_t *agent;
+ dx_config_t *config;
};
#endif
diff --git a/extras/dispatch/tests/CMakeLists.txt b/extras/dispatch/tests/CMakeLists.txt
index 688e1de2f6..3d90f163b3 100644
--- a/extras/dispatch/tests/CMakeLists.txt
+++ b/extras/dispatch/tests/CMakeLists.txt
@@ -48,4 +48,4 @@ add_test(unit_tests_size_5 unit_tests_size 5)
add_test(unit_tests_size_3 unit_tests_size 3)
add_test(unit_tests_size_2 unit_tests_size 2)
add_test(unit_tests_size_1 unit_tests_size 1)
-add_test(unit_tests unit_tests)
+add_test(unit_tests unit_tests ${CMAKE_CURRENT_SOURCE_DIR}/threads4.conf)
diff --git a/extras/dispatch/tests/run_unit_tests.c b/extras/dispatch/tests/run_unit_tests.c
index 9b0b5b100e..4b83d84b40 100644
--- a/extras/dispatch/tests/run_unit_tests.c
+++ b/extras/dispatch/tests/run_unit_tests.c
@@ -18,6 +18,7 @@
*/
#include <qpid/dispatch/buffer.h>
+#include <stdio.h>
int tool_tests();
int timer_tests();
@@ -26,11 +27,16 @@ int server_tests();
int main(int argc, char** argv)
{
+ if (argc != 2) {
+ fprintf(stderr, "usage: %s <config-file>\n", argv[0]);
+ exit(1);
+ }
+
int result = 0;
result += tool_tests();
result += timer_tests();
result += alloc_tests();
- result += server_tests();
+ result += server_tests(argv[1]);
return result;
}
diff --git a/extras/dispatch/tests/server_test.c b/extras/dispatch/tests/server_test.c
index deb3ae78eb..525d8b6a9f 100644
--- a/extras/dispatch/tests/server_test.c
+++ b/extras/dispatch/tests/server_test.c
@@ -29,6 +29,7 @@
#define THREAD_COUNT 4
#define OCTET_COUNT 100
+static const char *config_file;
static dx_dispatch_t *dx;
static sys_mutex_t *test_lock;
@@ -116,7 +117,7 @@ static char* test_start_handler(void *context)
{
int i;
- dx = dx_dispatch(THREAD_COUNT, 0, 0, 0);
+ dx = dx_dispatch(config_file);
expected_context = (void*) 0x00112233;
stored_error[0] = 0x0;
@@ -139,7 +140,7 @@ static char* test_start_handler(void *context)
static char *test_server_start(void *context)
{
- dx = dx_dispatch(THREAD_COUNT, 0, 0, 0);
+ dx = dx_dispatch(config_file);
dx_server_start(dx);
dx_server_stop(dx);
dx_dispatch_free(dx);
@@ -153,7 +154,7 @@ static char* test_user_fd(void *context)
int res;
dx_timer_t *timer;
- dx = dx_dispatch(THREAD_COUNT, 0, 0, 0);
+ dx = dx_dispatch(config_file);
dx_server_set_user_fd_handler(dx, ufd_handler);
timer = dx_timer(dx, fd_test_start, 0);
dx_timer_schedule(timer, 0);
@@ -190,12 +191,14 @@ static char* test_user_fd(void *context)
}
-int server_tests(void)
+int server_tests(const char *_config_file)
{
int result = 0;
test_lock = sys_mutex();
dx_log_set_mask(LOG_NONE);
+ config_file = _config_file;
+
TEST_CASE(test_server_start, 0);
TEST_CASE(test_start_handler, 0);
TEST_CASE(test_user_fd, 0);
diff --git a/extras/dispatch/tests/threads4.conf b/extras/dispatch/tests/threads4.conf
new file mode 100644
index 0000000000..1466e11cca
--- /dev/null
+++ b/extras/dispatch/tests/threads4.conf
@@ -0,0 +1,26 @@
+##
+## 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
+##
+
+
+##
+## Container section - Configures the general operation of the AMQP container.
+##
+container {
+ worker-threads: 4
+}