From 0425aadc78680e53000fd0108b540d6eca048516 Mon Sep 17 00:00:00 2001 From: gmcdonald Date: Sat, 13 Feb 2010 01:32:03 +0000 Subject: Moving axis svn, part of TLP move INFRA-2441 git-svn-id: http://svn.apache.org/repos/asf/axis/axis2/c/core/trunk@909681 13f79535-47bb-0310-9956-ffa450edef68 --- src/core/transport/amqp/Makefile.am | 4 + src/core/transport/amqp/receiver/Makefile.am | 25 + .../transport/amqp/receiver/axis2_amqp_receiver.c | 275 +++++++ .../transport/amqp/receiver/axis2_amqp_receiver.h | 82 ++ .../amqp/receiver/qpid_receiver/Makefile.am | 29 + .../receiver/qpid_receiver/axis2_qpid_receiver.cpp | 167 +++++ .../receiver/qpid_receiver/axis2_qpid_receiver.h | 39 + .../axis2_qpid_receiver_interface.cpp | 102 +++ .../qpid_receiver/axis2_qpid_receiver_interface.h | 58 ++ .../qpid_receiver/axis2_qpid_receiver_listener.cpp | 123 +++ .../qpid_receiver/axis2_qpid_receiver_listener.h | 43 ++ .../qpid_receiver/request_processor/Makefile.am | 20 + .../axis2_amqp_request_processor.c | 334 +++++++++ .../axis2_amqp_request_processor.h | 55 ++ src/core/transport/amqp/sender/Makefile.am | 26 + src/core/transport/amqp/sender/axis2_amqp_sender.c | 344 +++++++++ src/core/transport/amqp/sender/axis2_amqp_sender.h | 63 ++ .../transport/amqp/sender/qpid_sender/Makefile.am | 23 + .../amqp/sender/qpid_sender/axis2_qpid_sender.cpp | 242 ++++++ .../amqp/sender/qpid_sender/axis2_qpid_sender.h | 49 ++ .../qpid_sender/axis2_qpid_sender_interface.cpp | 130 ++++ .../qpid_sender/axis2_qpid_sender_interface.h | 50 ++ src/core/transport/amqp/server/Makefile.am | 1 + .../amqp/server/axis2_amqp_server/Makefile.am | 33 + .../server/axis2_amqp_server/axis2_amqp_server.c | 232 ++++++ .../server/axis2_amqp_server/axis2_amqp_server.h | 41 + src/core/transport/amqp/util/Makefile.am | 18 + src/core/transport/amqp/util/axis2_amqp_defines.h | 65 ++ src/core/transport/amqp/util/axis2_amqp_util.c | 823 +++++++++++++++++++++ src/core/transport/amqp/util/axis2_amqp_util.h | 143 ++++ 30 files changed, 3639 insertions(+) create mode 100644 src/core/transport/amqp/Makefile.am create mode 100644 src/core/transport/amqp/receiver/Makefile.am create mode 100644 src/core/transport/amqp/receiver/axis2_amqp_receiver.c create mode 100644 src/core/transport/amqp/receiver/axis2_amqp_receiver.h create mode 100644 src/core/transport/amqp/receiver/qpid_receiver/Makefile.am create mode 100644 src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver.cpp create mode 100644 src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver.h create mode 100644 src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver_interface.cpp create mode 100644 src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver_interface.h create mode 100644 src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver_listener.cpp create mode 100644 src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver_listener.h create mode 100644 src/core/transport/amqp/receiver/qpid_receiver/request_processor/Makefile.am create mode 100644 src/core/transport/amqp/receiver/qpid_receiver/request_processor/axis2_amqp_request_processor.c create mode 100644 src/core/transport/amqp/receiver/qpid_receiver/request_processor/axis2_amqp_request_processor.h create mode 100644 src/core/transport/amqp/sender/Makefile.am create mode 100644 src/core/transport/amqp/sender/axis2_amqp_sender.c create mode 100644 src/core/transport/amqp/sender/axis2_amqp_sender.h create mode 100644 src/core/transport/amqp/sender/qpid_sender/Makefile.am create mode 100644 src/core/transport/amqp/sender/qpid_sender/axis2_qpid_sender.cpp create mode 100644 src/core/transport/amqp/sender/qpid_sender/axis2_qpid_sender.h create mode 100644 src/core/transport/amqp/sender/qpid_sender/axis2_qpid_sender_interface.cpp create mode 100644 src/core/transport/amqp/sender/qpid_sender/axis2_qpid_sender_interface.h create mode 100644 src/core/transport/amqp/server/Makefile.am create mode 100644 src/core/transport/amqp/server/axis2_amqp_server/Makefile.am create mode 100644 src/core/transport/amqp/server/axis2_amqp_server/axis2_amqp_server.c create mode 100644 src/core/transport/amqp/server/axis2_amqp_server/axis2_amqp_server.h create mode 100644 src/core/transport/amqp/util/Makefile.am create mode 100644 src/core/transport/amqp/util/axis2_amqp_defines.h create mode 100644 src/core/transport/amqp/util/axis2_amqp_util.c create mode 100644 src/core/transport/amqp/util/axis2_amqp_util.h (limited to 'src/core/transport/amqp') diff --git a/src/core/transport/amqp/Makefile.am b/src/core/transport/amqp/Makefile.am new file mode 100644 index 0000000..ca5e58d --- /dev/null +++ b/src/core/transport/amqp/Makefile.am @@ -0,0 +1,4 @@ +SUBDIRS = util \ + receiver \ + server \ + sender diff --git a/src/core/transport/amqp/receiver/Makefile.am b/src/core/transport/amqp/receiver/Makefile.am new file mode 100644 index 0000000..4e16b0f --- /dev/null +++ b/src/core/transport/amqp/receiver/Makefile.am @@ -0,0 +1,25 @@ +SUBDIRS = qpid_receiver + +lib_LTLIBRARIES = libaxis2_amqp_receiver.la + +libaxis2_amqp_receiver_la_SOURCES = axis2_amqp_receiver.c + +libaxis2_amqp_receiver_la_LIBADD = $(top_builddir)/util/src/libaxutil.la \ + $(top_builddir)/src/core/transport/amqp/util/libaxis2_amqp_util.la \ + $(top_builddir)/src/core/transport/amqp/receiver/qpid_receiver/libaxis2_qpid_receiver.la + +libaxis2_amqp_receiver_la_LDFLAGS = -version-info $(VERSION_NO) + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/core/transport/amqp/util \ + -I$(top_builddir)/src/core/transport/amqp/receiver \ + -I$(top_builddir)/src/core/transport/amqp/sender/qpid_sender \ + -I$(top_builddir)/src/core/transport/amqp/receiver/qpid_receiver \ + -I$(top_builddir)/src/core/description \ + -I$(top_builddir)/src/core/context \ + -I$(top_builddir)/src/core/phaseresolver \ + -I$(top_builddir)/src/core/engine \ + -I$(top_builddir)/src/core/deployment \ + -I$(top_builddir)/util/include \ + -I$(top_builddir)/axiom/include + diff --git a/src/core/transport/amqp/receiver/axis2_amqp_receiver.c b/src/core/transport/amqp/receiver/axis2_amqp_receiver.c new file mode 100644 index 0000000..5ff69af --- /dev/null +++ b/src/core/transport/amqp/receiver/axis2_amqp_receiver.c @@ -0,0 +1,275 @@ +/* + * 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 +#include +#include + +static const axis2_transport_receiver_ops_t amqp_receiver_ops = +{ + axis2_amqp_receiver_init, + axis2_amqp_receiver_start, + axis2_amqp_receiver_get_reply_to_epr, + axis2_amqp_receiver_get_conf_ctx, + axis2_amqp_receiver_is_running, + axis2_amqp_receiver_stop, + axis2_amqp_receiver_free +}; + +AXIS2_EXTERN axis2_transport_receiver_t* AXIS2_CALL +axis2_amqp_receiver_create( + const axutil_env_t* env, + const axis2_char_t* repo, + const axis2_char_t* qpid_broker_ip, + int qpid_broker_port) +{ + AXIS2_ENV_CHECK(env, NULL); + + axis2_amqp_receiver_resource_pack_t* receiver_resource_pack = NULL; + + receiver_resource_pack = (axis2_amqp_receiver_resource_pack_t*)AXIS2_MALLOC(env->allocator, + sizeof(axis2_amqp_receiver_resource_pack_t)); + + if(!receiver_resource_pack) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + receiver_resource_pack->receiver.ops = &amqp_receiver_ops; + receiver_resource_pack->qpid_receiver = NULL; + receiver_resource_pack->conf_ctx = NULL; + receiver_resource_pack->conf_ctx_private = NULL; + + if(repo) + { + /** + * 1. We first create a private conf ctx which is owned by this server + * we only free this private conf context. We should never free the + * receiver_impl->conf_ctx because it may be owned by any other object which + * may lead to double free. + * + * 2. The Qpid broker IP and port are set in conf_ctx at two different places. + * If the repo is specified, they are set here. Otherwise, they are set + * in axis2_amqp_receiver_init method. + */ + axutil_property_t* property = NULL; + const axis2_char_t* broker_ip = NULL; + int* broker_port = (int*)AXIS2_MALLOC(env->allocator, sizeof(int)); + *broker_port = AXIS2_QPID_NULL_CONF_INT; + + receiver_resource_pack->conf_ctx_private = axis2_build_conf_ctx(env, repo); + if(!receiver_resource_pack->conf_ctx_private) + { + axis2_amqp_receiver_free((axis2_transport_receiver_t *)receiver_resource_pack, env); + return NULL; + } + + /* Set broker IP */ + broker_ip = qpid_broker_ip ? qpid_broker_ip : AXIS2_QPID_DEFAULT_BROKER_IP; + property = axutil_property_create_with_args(env, AXIS2_SCOPE_APPLICATION, 0, 0, + (void*)broker_ip); + axis2_conf_ctx_set_property(receiver_resource_pack->conf_ctx_private, env, + AXIS2_AMQP_CONF_CTX_PROPERTY_BROKER_IP, property); + + /* Set broker port */ + *broker_port = (qpid_broker_port != AXIS2_QPID_NULL_CONF_INT) ? qpid_broker_port + : AXIS2_QPID_DEFAULT_BROKER_PORT; + property = axutil_property_create_with_args(env, AXIS2_SCOPE_APPLICATION, 0, 0, + (void*)broker_port); + axis2_conf_ctx_set_property(receiver_resource_pack->conf_ctx_private, env, + AXIS2_AMQP_CONF_CTX_PROPERTY_BROKER_PORT, property); + + receiver_resource_pack->conf_ctx = receiver_resource_pack->conf_ctx_private; + } + + return &(receiver_resource_pack->receiver); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_amqp_receiver_init( + axis2_transport_receiver_t* receiver, + const axutil_env_t* env, + axis2_conf_ctx_t* conf_ctx, + axis2_transport_in_desc_t* in_desc) +{ + axis2_amqp_receiver_resource_pack_t* receiver_resource_pack = NULL; + axutil_property_t* property = NULL; + const axis2_char_t* broker_ip = NULL; + int* broker_port = (int*)AXIS2_MALLOC(env->allocator, sizeof(int)); + *broker_port = AXIS2_QPID_NULL_CONF_INT; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + receiver_resource_pack = AXIS2_AMQP_RECEIVER_TO_RESOURCE_PACK(receiver); + receiver_resource_pack->conf_ctx = conf_ctx; + + /* Set broker IP */ + broker_ip = axis2_amqp_util_get_in_desc_conf_value_string(in_desc, env, + AXIS2_AMQP_CONF_QPID_BROKER_IP); + if(!broker_ip) + { + broker_ip = AXIS2_QPID_DEFAULT_BROKER_IP; + } + property = axutil_property_create_with_args(env, AXIS2_SCOPE_APPLICATION, 0, 0, + (void*)broker_ip); + axis2_conf_ctx_set_property(receiver_resource_pack->conf_ctx, env, + AXIS2_AMQP_CONF_CTX_PROPERTY_BROKER_IP, property); + + /* Set broker port */ + *broker_port = axis2_amqp_util_get_in_desc_conf_value_int(in_desc, env, + AXIS2_AMQP_CONF_QPID_BROKER_PORT); + if(*broker_port == AXIS2_QPID_NULL_CONF_INT) + { + *broker_port = AXIS2_QPID_DEFAULT_BROKER_PORT; + } + property = axutil_property_create_with_args(env, AXIS2_SCOPE_APPLICATION, 0, 0, + (void*)broker_port); + axis2_conf_ctx_set_property(receiver_resource_pack->conf_ctx, env, + AXIS2_AMQP_CONF_CTX_PROPERTY_BROKER_PORT, property); + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_amqp_receiver_start( + axis2_transport_receiver_t* receiver, + const axutil_env_t* env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + axis2_status_t status = AXIS2_FAILURE; + + axis2_amqp_receiver_resource_pack_t* amqp_receiver_resource_pack = NULL; + axis2_qpid_receiver_resource_pack_t* qpid_receiver_resource_pack = NULL; + + amqp_receiver_resource_pack = AXIS2_AMQP_RECEIVER_TO_RESOURCE_PACK(receiver); + + /* Create Qpid Receiver */ + qpid_receiver_resource_pack = axis2_qpid_receiver_create(env, + amqp_receiver_resource_pack->conf_ctx); + + if(qpid_receiver_resource_pack) + { + amqp_receiver_resource_pack->qpid_receiver = qpid_receiver_resource_pack; + + status = axis2_qpid_receiver_start(qpid_receiver_resource_pack, env); + } + + return status; +} + +AXIS2_EXTERN axis2_endpoint_ref_t* AXIS2_CALL +axis2_amqp_receiver_get_reply_to_epr( + axis2_transport_receiver_t* receiver, + const axutil_env_t* env, + const axis2_char_t* svc_name) +{ + return NULL; +} + +AXIS2_EXTERN axis2_conf_ctx_t* AXIS2_CALL +axis2_amqp_receiver_get_conf_ctx( + axis2_transport_receiver_t* receiver, + const axutil_env_t* env) +{ + AXIS2_ENV_CHECK(env, NULL); + + return AXIS2_AMQP_RECEIVER_TO_RESOURCE_PACK(receiver)->conf_ctx; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_amqp_receiver_is_running( + axis2_transport_receiver_t* receiver, + const axutil_env_t* env) +{ + return AXIS2_TRUE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_amqp_receiver_stop( + axis2_transport_receiver_t* receiver, + const axutil_env_t* env) +{ + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_amqp_receiver_free( + axis2_transport_receiver_t* receiver, + const axutil_env_t* env) +{ + AXIS2_ENV_CHECK(env, void); + + axis2_amqp_receiver_resource_pack_t* receiver_resource_pack = NULL; + receiver_resource_pack = AXIS2_AMQP_RECEIVER_TO_RESOURCE_PACK(receiver); + + if(receiver_resource_pack->qpid_receiver) + { + axis2_qpid_receiver_free(receiver_resource_pack->qpid_receiver, env); + receiver_resource_pack->qpid_receiver = NULL; + } + + if(receiver_resource_pack->conf_ctx_private) + { + axis2_conf_ctx_free(receiver_resource_pack->conf_ctx_private, env); + receiver_resource_pack->conf_ctx_private = NULL; + } + + receiver_resource_pack->conf_ctx = NULL; /* Do not free this. It may be owned by some other object */ + + AXIS2_FREE(env->allocator, receiver_resource_pack); +} + +/* Library Exports */ + +AXIS2_EXPORT int +#ifndef AXIS2_STATIC_DEPLOY +axis2_get_instance( +#else + axis2_amqp_receiver_get_instance( +#endif + struct axis2_transport_receiver** inst, + const axutil_env_t* env) +{ + int status = AXIS2_SUCCESS; + + *inst = axis2_amqp_receiver_create(env, NULL, NULL, AXIS2_QPID_NULL_CONF_INT); + if(!(*inst)) + { + status = AXIS2_FAILURE; + } + + return status; +} + +AXIS2_EXPORT int +#ifndef AXIS2_STATIC_DEPLOY +axis2_remove_instance( +#else + axis2_amqp_receiver_remove_instance( +#endif + axis2_transport_receiver_t* inst, + const axutil_env_t* env) +{ + if(inst) + { + axis2_transport_receiver_free(inst, env); + } + + return AXIS2_SUCCESS; +} diff --git a/src/core/transport/amqp/receiver/axis2_amqp_receiver.h b/src/core/transport/amqp/receiver/axis2_amqp_receiver.h new file mode 100644 index 0000000..209e2bb --- /dev/null +++ b/src/core/transport/amqp/receiver/axis2_amqp_receiver.h @@ -0,0 +1,82 @@ +/* +* 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. +*/ + +#ifndef AXIS2_AMQP_RECEIVER_H +#define AXIS2_AMQP_RECEIVER_H + +#include +#include +#include + +typedef struct axis2_amqp_receiver_resource_pack +{ + axis2_transport_receiver_t receiver; + axis2_qpid_receiver_resource_pack_t* qpid_receiver; + axis2_conf_ctx_t* conf_ctx; + axis2_conf_ctx_t* conf_ctx_private; +} +axis2_amqp_receiver_resource_pack_t; + +#define AXIS2_AMQP_RECEIVER_TO_RESOURCE_PACK(amqp_receiver) \ + ((axis2_amqp_receiver_resource_pack_t*)(amqp_receiver)) + +AXIS2_EXTERN axis2_transport_receiver_t* AXIS2_CALL +axis2_amqp_receiver_create( + const axutil_env_t* env, + const axis2_char_t* repo, + const axis2_char_t* qpid_broker_ip, + int qpid_broker_port); + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_amqp_receiver_init( + axis2_transport_receiver_t* receiver, + const axutil_env_t* env, + axis2_conf_ctx_t* conf_ctx, + axis2_transport_in_desc_t* in_desc); + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_amqp_receiver_start( + axis2_transport_receiver_t* receiver, + const axutil_env_t* env); + +AXIS2_EXTERN axis2_endpoint_ref_t* AXIS2_CALL +axis2_amqp_receiver_get_reply_to_epr( + axis2_transport_receiver_t* receiver, + const axutil_env_t* env, + const axis2_char_t* svc_name); + +AXIS2_EXTERN axis2_conf_ctx_t* AXIS2_CALL +axis2_amqp_receiver_get_conf_ctx( + axis2_transport_receiver_t* receiver, + const axutil_env_t* env); + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_amqp_receiver_is_running( + axis2_transport_receiver_t* receiver, + const axutil_env_t* env); + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_amqp_receiver_stop( + axis2_transport_receiver_t* receiver, + const axutil_env_t* env); + +AXIS2_EXTERN void AXIS2_CALL +axis2_amqp_receiver_free( + axis2_transport_receiver_t* receiver, + const axutil_env_t* env); + +#endif diff --git a/src/core/transport/amqp/receiver/qpid_receiver/Makefile.am b/src/core/transport/amqp/receiver/qpid_receiver/Makefile.am new file mode 100644 index 0000000..3ecdf34 --- /dev/null +++ b/src/core/transport/amqp/receiver/qpid_receiver/Makefile.am @@ -0,0 +1,29 @@ +SUBDIRS = request_processor + +lib_LTLIBRARIES = libaxis2_qpid_receiver.la + +libaxis2_qpid_receiver_la_SOURCES = axis2_qpid_receiver.cpp \ + axis2_qpid_receiver_interface.cpp \ + axis2_qpid_receiver_listener.cpp + +libaxis2_qpid_receiver_la_LIBADD = $(top_builddir)/util/src/libaxutil.la \ + $(QPID_HOME)/lib/libqpidclient.la \ + $(top_builddir)/src/core/transport/amqp/util/libaxis2_amqp_util.la \ + $(top_builddir)/src/core/transport/amqp/receiver/qpid_receiver/request_processor/libaxis2_amqp_request_processor.la + +libaxis2_qpid_receiver_la_LDFLAGS = g++ -version-info $(VERSION_NO) + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/core/transport/amqp/receiver/qpid_receiver \ + -I$(top_builddir)/src/core/transport/amqp/receiver/qpid_receiver/request_processor \ + -I$(top_builddir)/src/core/transport/amqp/util \ + -I$(top_builddir)/src/core/transport/amqp/sender/qpid_sender \ + -I$(top_builddir)/src/core/description \ + -I$(top_builddir)/src/core/context \ + -I$(top_builddir)/src/core/phaseresolver \ + -I$(top_builddir)/src/core/engine \ + -I$(top_builddir)/src/core/deployment \ + -I$(top_builddir)/util/include \ + -I$(top_builddir)/axiom/include \ + -I$(QPID_HOME)/include + diff --git a/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver.cpp b/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver.cpp new file mode 100644 index 0000000..140ab0e --- /dev/null +++ b/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver.cpp @@ -0,0 +1,167 @@ +/* + * 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 + * + * tcp://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 +#include +#include +#include +#include +#include +#include +#include +#include + +Axis2QpidReceiver::Axis2QpidReceiver( + const axutil_env_t* env, + axis2_conf_ctx_t* conf_ctx) +{ + this->env = env; + this->conf_ctx = conf_ctx; +} + +Axis2QpidReceiver::~Axis2QpidReceiver( + void) +{ +} + +bool +Axis2QpidReceiver::start( + void) +{ + if(!conf_ctx) + return false; + + Connection connection; + axis2_bool_t serverSide = AXIS2_TRUE; + + serverSide = axis2_amqp_util_conf_ctx_get_server_side(conf_ctx, env); + + while(true) + { + try + { + std::list queueNameList; + string qpidBrokerIP = axis2_amqp_util_conf_ctx_get_qpid_broker_ip(conf_ctx, env); + int qpidBrokerPort = axis2_amqp_util_conf_ctx_get_qpid_broker_port(conf_ctx, env); + + /* Check if Client Side and Resolve Dynamic Queue Name */ + if(serverSide == AXIS2_TRUE) /* Server side */ + { + std::cout << "Connecting to Qpid Broker on " << qpidBrokerIP << ":" + << qpidBrokerPort << " ... "; + } + + /* Create Connection to Qpid Broker */ + connection.open(qpidBrokerIP, qpidBrokerPort); + + if(serverSide == AXIS2_TRUE) /* Server side */ + { + /* Create queue for each service. Queue name is equal to service name */ + axis2_conf_t* conf = axis2_conf_ctx_get_conf(conf_ctx, env); + if(!conf) + return false; + + axutil_hash_t* serviceMap = axis2_conf_get_all_svcs(conf, env); + if(!serviceMap) + return false; + + axutil_hash_index_t* serviceHI = NULL; + void* serviceValue = NULL; + + for(serviceHI = axutil_hash_first(serviceMap, env); serviceHI; serviceHI + = axutil_hash_next(env, serviceHI)) + { + axutil_hash_this(serviceHI, NULL, NULL, &serviceValue); + + axis2_svc_t* service = (axis2_svc_t*)serviceValue; + if(!service) + return false; + + axis2_char_t* serviceName = axutil_qname_get_localpart(axis2_svc_get_qname( + service, env), env); + if(!serviceName) + return false; + + queueNameList.push_back(serviceName); + } + + std::cout << "CONNECTED" << std::endl; + } + else /* Client side separate listener in dual-channel case */ + { + string queueName = axis2_amqp_util_conf_ctx_get_dual_channel_queue_name(conf_ctx, + env); + + queueNameList.push_back(queueName); + } + + /* Create new session */ + Session session = connection.newSession(); + + /* Create Subscription manager */ + SubscriptionManager subscriptionManager(session); + + Axis2QpidReceiverListener qpidReceiverListener(env, conf_ctx); + + /* Subscribe to queues */ + while(!queueNameList.empty()) + { + string queueName = queueNameList.front(); + + session.queueDeclare(arg::queue = queueName, arg::autoDelete = true); + session.exchangeBind(arg::exchange = AXIS2_AMQP_EXCHANGE_DIRECT, arg::queue + = queueName, arg::bindingKey = queueName); + + subscriptionManager.subscribe(qpidReceiverListener, queueName); + + queueNameList.pop_front(); + } + + /* Listen and Wait */ + if(serverSide == AXIS2_TRUE) /* Server side */ + { + std::cout << "Started Axis2 AMQP Server ..." << std::endl; + } + + subscriptionManager.run(); + + return true; + } + catch(const std::exception& e) + { + connection.close(); + + if(serverSide == AXIS2_TRUE) /* Server side */ + { + std::cout << "FAILED" << std::endl; + } + + sleep(5); + } + } + + connection.close(); + + return false; +} + +bool +Axis2QpidReceiver::shutdown( + void) +{ + return true; +} diff --git a/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver.h b/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver.h new file mode 100644 index 0000000..66108d5 --- /dev/null +++ b/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver.h @@ -0,0 +1,39 @@ +/* + * 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 + * + * tcp://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. + */ + +#ifndef AXIS2_QPID_RECEIVER_H +#define AXIS2_QPID_RECEIVER_H + +#include +#include + +class Axis2QpidReceiver +{ + public: + Axis2QpidReceiver(const axutil_env_t* env, + axis2_conf_ctx_t* conf_ctx); + ~Axis2QpidReceiver(void); + + bool start(void); + bool shutdown(void); + + private: + const axutil_env_t* env; + axis2_conf_ctx_t* conf_ctx; +}; + +#endif diff --git a/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver_interface.cpp b/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver_interface.cpp new file mode 100644 index 0000000..79faa86 --- /dev/null +++ b/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver_interface.cpp @@ -0,0 +1,102 @@ +/* +* 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 +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +AXIS2_EXTERN axis2_qpid_receiver_resource_pack_t* AXIS2_CALL +axis2_qpid_receiver_create( + const axutil_env_t* env, + axis2_conf_ctx_t* conf_ctx) +{ + AXIS2_ENV_CHECK(env, NULL); + + axis2_qpid_receiver_resource_pack_t* resource_pack = NULL; + + resource_pack = (axis2_qpid_receiver_resource_pack_t*)AXIS2_MALLOC + (env->allocator, sizeof(axis2_qpid_receiver_resource_pack_t)); + + if (!resource_pack) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + /* Create Qpid Receiver */ + Axis2QpidReceiver* qpid_receiver = new Axis2QpidReceiver(env, conf_ctx); + + resource_pack->qpid_receiver = qpid_receiver; + + return resource_pack; +} + + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_qpid_receiver_start( + axis2_qpid_receiver_resource_pack_t* receiver_resource_pack, + const axutil_env_t* env) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + axis2_status_t status = AXIS2_FAILURE; + + /* Start Qpid Receiver */ + Axis2QpidReceiver* qpid_receiver = (Axis2QpidReceiver*)receiver_resource_pack->qpid_receiver; + + if ((qpid_receiver) && (qpid_receiver->start())) + { + status = AXIS2_SUCCESS; + } + + return status; +} + + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_qpid_receiver_is_running( + axis2_qpid_receiver_resource_pack_t* receiver_resource_pack, + const axutil_env_t* env) +{ + return AXIS2_TRUE; +} + + +AXIS2_EXTERN void AXIS2_CALL +axis2_qpid_receiver_free( + axis2_qpid_receiver_resource_pack_t* receiver_resource_pack, + const axutil_env_t* env) +{ + AXIS2_ENV_CHECK(env, void); + + if (receiver_resource_pack) + { + Axis2QpidReceiver* qpid_receiver = (Axis2QpidReceiver*)receiver_resource_pack->qpid_receiver; + if (qpid_receiver) + delete qpid_receiver; + + AXIS2_FREE(env->allocator, receiver_resource_pack); + } +} + +#ifdef __cplusplus +} +#endif diff --git a/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver_interface.h b/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver_interface.h new file mode 100644 index 0000000..d141dfc --- /dev/null +++ b/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver_interface.h @@ -0,0 +1,58 @@ +/* +* 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. +*/ + +#ifndef AXIS2_QPID_RECEIVER_INTERFACE_H +#define AXIS2_QPID_RECEIVER_INTERFACE_H + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + typedef struct axis2_qpid_receiver_resource_pack + { + void* qpid_receiver; + }axis2_qpid_receiver_resource_pack_t; + + AXIS2_EXTERN axis2_qpid_receiver_resource_pack_t* AXIS2_CALL + axis2_qpid_receiver_create( + const axutil_env_t* env, + axis2_conf_ctx_t* conf_ctx); + + AXIS2_EXTERN axis2_status_t AXIS2_CALL + axis2_qpid_receiver_start( + axis2_qpid_receiver_resource_pack_t* receiver_resource_pack, + const axutil_env_t* env); + + AXIS2_EXTERN axis2_bool_t AXIS2_CALL + axis2_qpid_receiver_is_running( + axis2_qpid_receiver_resource_pack_t* receiver_resource_pack, + const axutil_env_t* env); + + AXIS2_EXTERN void AXIS2_CALL + axis2_qpid_receiver_free( + axis2_qpid_receiver_resource_pack_t* receiver_resource_pack, + const axutil_env_t* env); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver_listener.cpp b/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver_listener.cpp new file mode 100644 index 0000000..63717ca --- /dev/null +++ b/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver_listener.cpp @@ -0,0 +1,123 @@ +/* + * 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 + * + * tcp://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 +#include +#include +#include +#include +#include + +Axis2QpidReceiverListener::Axis2QpidReceiverListener( + const axutil_env_t* env, + axis2_conf_ctx_t* conf_ctx) +{ + this->env = env; + this->conf_ctx = conf_ctx; +} + +Axis2QpidReceiverListener::~Axis2QpidReceiverListener( + void) +{ +} + +void +Axis2QpidReceiverListener::received( + Message& message) +{ + AXIS2_ENV_CHECK(env, void); + + axis2_amqp_request_processor_resource_pack_t* request_data = NULL; +#ifdef AXIS2_SVR_MULTI_THREADED + axutil_thread_t* worker_thread = NULL; +#endif + + request_data = (axis2_amqp_request_processor_resource_pack_t*)AXIS2_MALLOC(env->allocator, + sizeof(axis2_amqp_request_processor_resource_pack_t)); + + if(!request_data) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Memory Allocation Error"); + return; + } + + request_data->env = (axutil_env_t*)env; + request_data->conf_ctx = conf_ctx; + + /* Create a Local Copy of Request Content */ + std::string message_data = message.getData(); + axis2_char_t* request_content = + (axis2_char_t*)AXIS2_MALLOC(env->allocator, message_data.size()); + memcpy(request_content, message_data.c_str(), message_data.size()); + + request_data->request_content = request_content; + request_data->content_length = message_data.size(); + + /* Set ReplyTo */ + request_data->reply_to = NULL; + if(message.getMessageProperties().hasReplyTo()) + { + /* Create a Local Copy of ReplyTo */ + std::string reply_to_tmp = message.getMessageProperties().getReplyTo().getRoutingKey(); + axis2_char_t* reply_to = (axis2_char_t*)AXIS2_MALLOC(env->allocator, reply_to_tmp.size() + + 1); + strcpy(reply_to, reply_to_tmp.c_str()); + + request_data->reply_to = reply_to; + } + + /* Copy AMQP headers */ + /* Content-Type */ + request_data->content_type = NULL; + std::string content_type_tmp = message.getHeaders().getAsString(AXIS2_AMQP_HEADER_CONTENT_TYPE); + if(!content_type_tmp.empty()) + { + axis2_char_t* content_type = (axis2_char_t*)AXIS2_MALLOC(env->allocator, + content_type_tmp.size() + 1); + strcpy(content_type, content_type_tmp.c_str()); + + request_data->content_type = content_type; + } + + /* SOAPAction */ + request_data->soap_action = NULL; + std::string soap_action_tmp = message.getHeaders().getAsString(AXIS2_AMQP_HEADER_SOAP_ACTION); + if(!soap_action_tmp.empty()) + { + axis2_char_t* soap_action = (axis2_char_t*)AXIS2_MALLOC(env->allocator, + soap_action_tmp.size() + 1); + strcpy(soap_action, soap_action_tmp.c_str()); + + request_data->soap_action = soap_action; + } + +#ifdef AXIS2_SVR_MULTI_THREADED + worker_thread = axutil_thread_pool_get_thread(env->thread_pool, + axis2_amqp_request_processor_thread_function, + (void*)request_data); + + if (!worker_thread) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to Create Thread"); + return; + } + + axutil_thread_pool_thread_detach(env->thread_pool, worker_thread); +#else + axis2_amqp_request_processor_thread_function(NULL, (void*)request_data); +#endif +} diff --git a/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver_listener.h b/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver_listener.h new file mode 100644 index 0000000..d5923db --- /dev/null +++ b/src/core/transport/amqp/receiver/qpid_receiver/axis2_qpid_receiver_listener.h @@ -0,0 +1,43 @@ +/* + * 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 + * + * tcp://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. + */ + +#ifndef AXIS2_QPID_RECEIVER_LISTENER_H +#define AXIS2_QPID_RECEIVER_LISTENER_H + +#include +#include +#include +#include + +using namespace qpid::client; +using namespace qpid::framing; + +class Axis2QpidReceiverListener : public MessageListener +{ + public: + Axis2QpidReceiverListener(const axutil_env_t* env, + axis2_conf_ctx_t* conf_ctx); + ~Axis2QpidReceiverListener(void); + + private: + virtual void received(Message& message); + + const axutil_env_t* env; + axis2_conf_ctx_t* conf_ctx; +}; + +#endif diff --git a/src/core/transport/amqp/receiver/qpid_receiver/request_processor/Makefile.am b/src/core/transport/amqp/receiver/qpid_receiver/request_processor/Makefile.am new file mode 100644 index 0000000..77cac4a --- /dev/null +++ b/src/core/transport/amqp/receiver/qpid_receiver/request_processor/Makefile.am @@ -0,0 +1,20 @@ +lib_LTLIBRARIES = libaxis2_amqp_request_processor.la + +libaxis2_amqp_request_processor_la_SOURCES = axis2_amqp_request_processor.c + +libaxis2_amqp_request_processor_la_LIBADD = $(top_builddir)/util/src/libaxutil.la \ + $(top_builddir)/src/core/transport/amqp/util/libaxis2_amqp_util.la + +libaxis2_amqp_request_processor_la_LDFLAGS = -version-info $(VERSION_NO) + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/core/transport/amqp/receiver/qpid_receiver/request_processor \ + -I$(top_builddir)/src/core/transport/amqp/util \ + -I$(top_builddir)/src/core/description \ + -I$(top_builddir)/src/core/context \ + -I$(top_builddir)/src/core/phaseresolver \ + -I$(top_builddir)/src/core/engine \ + -I$(top_builddir)/src/core/deployment \ + -I$(top_builddir)/util/include \ + -I$(top_builddir)/axiom/include + diff --git a/src/core/transport/amqp/receiver/qpid_receiver/request_processor/axis2_amqp_request_processor.c b/src/core/transport/amqp/receiver/qpid_receiver/request_processor/axis2_amqp_request_processor.c new file mode 100644 index 0000000..0e0c9f8 --- /dev/null +++ b/src/core/transport/amqp/receiver/qpid_receiver/request_processor/axis2_amqp_request_processor.c @@ -0,0 +1,334 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +void* AXIS2_THREAD_FUNC +axis2_amqp_request_processor_thread_function( + axutil_thread_t* thread, + void* request_data) +{ + axis2_status_t status = AXIS2_FAILURE; + axutil_env_t* env = NULL; + axutil_env_t* thread_env = NULL; + axis2_amqp_request_processor_resource_pack_t* request_resource_pack = NULL; + +#ifndef WIN32 +#ifdef AXIS2_SVR_MULTI_THREADED + signal(SIGPIPE, SIG_IGN); +#endif +#endif + + request_resource_pack = (axis2_amqp_request_processor_resource_pack_t*)request_data; + + env = request_resource_pack->env; + thread_env = axutil_init_thread_env(env); + + /* Process Request */ + status = axis2_amqp_process_request(thread_env, request_resource_pack); + + if(status == AXIS2_SUCCESS) + { + AXIS2_LOG_INFO(thread_env->log, "Request Processed Successfully"); + } + else + { + AXIS2_LOG_WARNING(thread_env->log, AXIS2_LOG_SI, "Error while Processing Request"); + } + + AXIS2_FREE(thread_env->allocator, request_resource_pack->request_content); + AXIS2_FREE(thread_env->allocator, request_resource_pack->reply_to); + AXIS2_FREE(thread_env->allocator, request_resource_pack->content_type); + AXIS2_FREE(thread_env->allocator, request_resource_pack->soap_action); + + AXIS2_FREE(thread_env->allocator, request_resource_pack); + + if(thread_env) + { + thread_env = NULL; + } + +#ifdef AXIS2_SVR_MULTI_THREADED + axutil_thread_pool_exit_thread(env->thread_pool, thread); +#endif + + return NULL; +} + +axis2_status_t +axis2_amqp_process_request( + const axutil_env_t* env, + axis2_amqp_request_processor_resource_pack_t* request_resource_pack) +{ + axiom_xml_reader_t* xml_reader = NULL; + axiom_stax_builder_t* stax_builder = NULL; + axiom_soap_builder_t* soap_builder = NULL; + axis2_transport_out_desc_t* out_desc = NULL; + axis2_transport_in_desc_t* in_desc = NULL; + axis2_msg_ctx_t* msg_ctx = NULL; + axiom_soap_envelope_t* soap_envelope = NULL; + axis2_engine_t* engine = NULL; + const axis2_char_t* soap_ns_uri = NULL; + axis2_bool_t is_soap_11 = AXIS2_FALSE; + axis2_char_t *soap_body_str = NULL; + int soap_body_len = 0; + axis2_bool_t is_mtom = AXIS2_FALSE; + axis2_status_t status = AXIS2_FAILURE; + axutil_hash_t *binary_data_map = NULL; + axiom_soap_body_t *soap_body = NULL; + axutil_property_t* reply_to_property = NULL; + + /* Create msg_ctx */ + if(!request_resource_pack->conf_ctx) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Conf Context not Available"); + return AXIS2_FAILURE; + } + + out_desc = axis2_conf_get_transport_out(axis2_conf_ctx_get_conf( + request_resource_pack->conf_ctx, env), env, AXIS2_TRANSPORT_ENUM_AMQP); + if(!out_desc) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Transport Out Descriptor not Found"); + return AXIS2_FAILURE; + } + + in_desc = axis2_conf_get_transport_in(axis2_conf_ctx_get_conf(request_resource_pack->conf_ctx, + env), env, AXIS2_TRANSPORT_ENUM_AMQP); + if(!in_desc) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Transport In Descriptor not Found"); + return AXIS2_FAILURE; + } + + /* Create msg_ctx */ + msg_ctx = axis2_msg_ctx_create(env, request_resource_pack->conf_ctx, in_desc, out_desc); + + axis2_msg_ctx_set_server_side(msg_ctx, env, AXIS2_TRUE); + + /* Handle MTOM */ + if(strstr(request_resource_pack->content_type, AXIS2_AMQP_HEADER_ACCEPT_MULTIPART_RELATED)) + { + axis2_char_t* mime_boundary = axis2_amqp_util_get_value_from_content_type(env, + request_resource_pack->content_type, AXIS2_AMQP_HEADER_CONTENT_TYPE_MIME_BOUNDARY); + + if(mime_boundary) + { + axiom_mime_parser_t *mime_parser = NULL; + int soap_body_len = 0; + axutil_param_t *buffer_size_param = NULL; + axutil_param_t *max_buffers_param = NULL; + axutil_param_t *attachment_dir_param = NULL; + axis2_char_t *value_size = NULL; + axis2_char_t *value_num = NULL; + axis2_char_t *value_dir = NULL; + int size = 0; + int num = 0; + + mime_parser = axiom_mime_parser_create(env); + + buffer_size_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_MTOM_BUFFER_SIZE); + if(buffer_size_param) + { + value_size = (axis2_char_t*)axutil_param_get_value(buffer_size_param, env); + if(value_size) + { + size = atoi(value_size); + axiom_mime_parser_set_buffer_size(mime_parser, env, size); + } + } + + max_buffers_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_MTOM_MAX_BUFFERS); + if(max_buffers_param) + { + value_num = (axis2_char_t*)axutil_param_get_value(max_buffers_param, env); + if(value_num) + { + num = atoi(value_num); + axiom_mime_parser_set_max_buffers(mime_parser, env, num); + } + } + + /* If this paramter is there mime_parser will cached the attachment + * using to the directory for large attachments. */ + attachment_dir_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_ATTACHMENT_DIR); + if(attachment_dir_param) + { + value_dir = (axis2_char_t*)axutil_param_get_value(attachment_dir_param, env); + if(value_dir) + { + axiom_mime_parser_set_attachment_dir(mime_parser, env, value_dir); + } + } + + if(mime_parser) + { + axis2_callback_info_t *callback_ctx = NULL; + axutil_stream_t *stream = NULL; + + callback_ctx = AXIS2_MALLOC(env->allocator, sizeof(axis2_callback_info_t)); + + stream = axutil_stream_create_basic(env); + if(stream) + { + axutil_stream_write(stream, env, request_resource_pack->request_content, + request_resource_pack->content_length); + callback_ctx->env = env; + callback_ctx->in_stream = stream; + callback_ctx->content_length = request_resource_pack->content_length; + callback_ctx->unread_len = request_resource_pack->content_length; + callback_ctx->chunked_stream = NULL; + } + + /*binary_data_map = + axiom_mime_parser_parse(mime_parser, env, + axis2_amqp_util_on_data_request, + (void*)callback_ctx, + mime_boundary);*/ + if(!binary_data_map) + { + return AXIS2_FAILURE; + } + + soap_body_str = axiom_mime_parser_get_soap_body_str(mime_parser, env); + soap_body_len = axiom_mime_parser_get_soap_body_len(mime_parser, env); + + axutil_stream_free(stream, env); + AXIS2_FREE(env->allocator, callback_ctx); + axiom_mime_parser_free(mime_parser, env); + } + + AXIS2_FREE(env->allocator, mime_boundary); + } + + is_mtom = AXIS2_TRUE; + } + else + { + soap_body_str = request_resource_pack->request_content; + soap_body_len = request_resource_pack->content_length; + } + + soap_body_len = axutil_strlen(soap_body_str); + + xml_reader = axiom_xml_reader_create_for_memory(env, soap_body_str, soap_body_len, NULL, + AXIS2_XML_PARSER_TYPE_BUFFER); + if(!xml_reader) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to Create XML Reader"); + return AXIS2_FAILURE; + } + + stax_builder = axiom_stax_builder_create(env, xml_reader); + if(!stax_builder) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to Create StAX Builder"); + return AXIS2_FAILURE; + } + + soap_ns_uri = AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI; + + if(request_resource_pack->content_type) + { + if(strstr(request_resource_pack->content_type, AXIS2_AMQP_HEADER_ACCEPT_TEXT_XML)) + { + is_soap_11 = AXIS2_TRUE; + soap_ns_uri = AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI; + } + /*if (strstr(request_resource_pack->content_type, AXIS2_AMQP_HEADER_ACCEPT_APPL_SOAP)) + { + is_soap_11 = AXIS2_FALSE; + soap_ns_uri = AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI; + } + else if (strstr(request_resource_pack->content_type, AXIS2_AMQP_HEADER_ACCEPT_TEXT_XML)) + { + is_soap_11 = AXIS2_TRUE; + soap_ns_uri = AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI; + }*/ + } + + soap_builder = axiom_soap_builder_create(env, stax_builder, soap_ns_uri); + if(!soap_builder) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to Create SOAP Builder"); + return AXIS2_FAILURE; + } + + if(binary_data_map) + { + axiom_soap_builder_set_mime_body_parts(soap_builder, env, binary_data_map); + } + + soap_envelope = axiom_soap_builder_get_soap_envelope(soap_builder, env); + axis2_msg_ctx_set_soap_envelope(msg_ctx, env, soap_envelope); + + soap_body = axiom_soap_envelope_get_body(soap_envelope, env); + + if(!soap_body) + { + return AXIS2_FAILURE; + } + + /* SOAPAction */ + if(request_resource_pack->soap_action) + { + axis2_msg_ctx_set_soap_action(msg_ctx, env, axutil_string_create(env, + request_resource_pack->soap_action)); + } + + /* SOAP version */ + axis2_msg_ctx_set_is_soap_11(msg_ctx, env, is_soap_11); + + /* Set ReplyTo in the msg_ctx as a property. This is used by the server when + * 1. WS-A is not in use + * 2. ReplyTo is an anonymous EPR - Sandesha2/Dual-channel */ + reply_to_property = axutil_property_create_with_args(env, AXIS2_SCOPE_REQUEST, 0, 0, + (void*)request_resource_pack->reply_to); + axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_AMQP_MSG_CTX_PROPERTY_REPLY_TO, + reply_to_property); + + engine = axis2_engine_create(env, request_resource_pack->conf_ctx); + + if(AXIS2_TRUE == axiom_soap_body_has_fault(soap_body, env)) + { + status = axis2_engine_receive_fault(engine, env, msg_ctx); + } + else + { + status = axis2_engine_receive(engine, env, msg_ctx); + } + + if(engine) + { + axis2_engine_free(engine, env); + } + + if(soap_body_str && is_mtom) + { + AXIS2_FREE(env->allocator, soap_body_str); + } + + return status; +} diff --git a/src/core/transport/amqp/receiver/qpid_receiver/request_processor/axis2_amqp_request_processor.h b/src/core/transport/amqp/receiver/qpid_receiver/request_processor/axis2_amqp_request_processor.h new file mode 100644 index 0000000..97f13b2 --- /dev/null +++ b/src/core/transport/amqp/receiver/qpid_receiver/request_processor/axis2_amqp_request_processor.h @@ -0,0 +1,55 @@ +/* + * 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. + */ + +#ifndef AXIS2_AMQP_REQUEST_PROCESSOR_H +#define AXIS2_AMQP_REQUEST_PROCESSOR_H + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + typedef struct axis2_amqp_request_processor_resource_pack + { + axutil_env_t* env; + axis2_conf_ctx_t* conf_ctx; + axis2_char_t* request_content; + int content_length; + axis2_char_t* reply_to; + axis2_char_t* content_type; + axis2_char_t* soap_action; + } axis2_amqp_request_processor_resource_pack_t; + + /* The worker thread function */ + void* AXIS2_THREAD_FUNC + axis2_amqp_request_processor_thread_function( + axutil_thread_t* thread, + void* request_data); + + axis2_status_t + axis2_amqp_process_request( + const axutil_env_t* env, + axis2_amqp_request_processor_resource_pack_t* request_resource_pack); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/core/transport/amqp/sender/Makefile.am b/src/core/transport/amqp/sender/Makefile.am new file mode 100644 index 0000000..8af0c7b --- /dev/null +++ b/src/core/transport/amqp/sender/Makefile.am @@ -0,0 +1,26 @@ +SUBDIRS = qpid_sender + +lib_LTLIBRARIES = libaxis2_amqp_sender.la + +libaxis2_amqp_sender_la_SOURCES = axis2_amqp_sender.c + +libaxis2_amqp_sender_la_LIBADD = $(top_builddir)/util/src/libaxutil.la \ + $(top_builddir)/src/core/transport/amqp/util/libaxis2_amqp_util.la \ + $(top_builddir)/src/core/transport/amqp/sender/qpid_sender/libaxis2_qpid_sender.la + +libaxis2_amqp_sender_la_LDFLAGS = -version-info $(VERSION_NO) + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/core/transport/amqp/util \ + -I$(top_builddir)/src/core/transport/amqp/receiver \ + -I$(top_builddir)/src/core/transport/amqp/receiver/qpid_receiver \ + -I$(top_builddir)/src/core/transport/amqp/sender \ + -I$(top_builddir)/src/core/transport/amqp/sender/qpid_sender \ + -I$(top_builddir)/src/core/description \ + -I$(top_builddir)/src/core/context \ + -I$(top_builddir)/src/core/phaseresolver \ + -I$(top_builddir)/src/core/engine \ + -I$(top_builddir)/src/core/deployment \ + -I$(top_builddir)/util/include \ + -I$(top_builddir)/axiom/include + diff --git a/src/core/transport/amqp/sender/axis2_amqp_sender.c b/src/core/transport/amqp/sender/axis2_amqp_sender.c new file mode 100644 index 0000000..aae5496 --- /dev/null +++ b/src/core/transport/amqp/sender/axis2_amqp_sender.c @@ -0,0 +1,344 @@ +/* + * 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 +#include +#include +#include +#include +#include + +static const axis2_transport_sender_ops_t amqp_sender_ops = +{ + axis2_amqp_sender_init, + axis2_amqp_sender_invoke, + axis2_amqp_sender_clean_up, + axis2_amqp_sender_free +}; + +AXIS2_EXTERN axis2_transport_sender_t* AXIS2_CALL +axis2_amqp_sender_create( + const axutil_env_t* env) +{ + AXIS2_ENV_CHECK(env, NULL); + + axis2_amqp_sender_resource_pack_t* sender_resource_pack = NULL; + + sender_resource_pack = (axis2_amqp_sender_resource_pack_t*)AXIS2_MALLOC(env->allocator, + sizeof(axis2_amqp_sender_resource_pack_t)); + + if(!sender_resource_pack) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return NULL; + } + + sender_resource_pack->sender.ops = &amqp_sender_ops; + sender_resource_pack->conf_ctx = NULL; + + return &(sender_resource_pack->sender); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_amqp_sender_init( + axis2_transport_sender_t* sender, + const axutil_env_t* env, + axis2_conf_ctx_t* conf_ctx, + axis2_transport_out_desc_t* out_desc) +{ + axis2_amqp_sender_resource_pack_t* sender_resource_pack = NULL; + axutil_property_t* property = NULL; + int* request_timeout = (int*)AXIS2_MALLOC(env->allocator, sizeof(int)); + *request_timeout = AXIS2_QPID_NULL_CONF_INT; + + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + + sender_resource_pack = AXIS2_AMQP_SENDER_TO_RESOURCE_PACK(sender); + sender_resource_pack->conf_ctx = conf_ctx; + + /* Set request timeout */ + *request_timeout = axis2_amqp_util_get_out_desc_conf_value_int(out_desc, env, + AXIS2_AMQP_CONF_QPID_REQUEST_TIMEOUT); + if(*request_timeout == AXIS2_QPID_NULL_CONF_INT) + { + *request_timeout = AXIS2_QPID_DEFAULT_REQUEST_TIMEOUT; + } + property = axutil_property_create_with_args(env, AXIS2_SCOPE_APPLICATION, 0, 0, + (void*)request_timeout); + axis2_conf_ctx_set_property(sender_resource_pack->conf_ctx, env, + AXIS2_AMQP_CONF_CTX_PROPERTY_REQUEST_TIMEOUT, property); + + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_amqp_sender_invoke( + axis2_transport_sender_t* sender, + const axutil_env_t* env, + axis2_msg_ctx_t* msg_ctx) +{ + AXIS2_ENV_CHECK(env, AXIS2_FAILURE); + AXIS2_PARAM_CHECK(env->error, msg_ctx, AXIS2_FAILURE); + + axiom_soap_envelope_t* request_soap_envelope = NULL; + axiom_xml_writer_t* xml_writer = NULL; + axiom_output_t* request_om_output = NULL; + axis2_char_t* request_content = NULL; + axis2_bool_t is_server = AXIS2_TRUE; + axis2_bool_t is_soap_11 = AXIS2_FALSE; + axutil_string_t* content_type = NULL; + const axis2_char_t* soap_action = NULL; + axis2_bool_t do_mtom = AXIS2_FALSE; + axis2_bool_t status = AXIS2_FAILURE; + + request_soap_envelope = axis2_msg_ctx_get_soap_envelope(msg_ctx, env); + + xml_writer = axiom_xml_writer_create_for_memory(env, NULL, AXIS2_TRUE, 0, + AXIS2_XML_PARSER_TYPE_BUFFER); + if(!xml_writer) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to Create XML Writer"); + return AXIS2_FAILURE; + } + + request_om_output = axiom_output_create(env, xml_writer); + if(!request_om_output) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to Create OM Output"); + axiom_xml_writer_free(xml_writer, env); + xml_writer = NULL; + return AXIS2_FAILURE; + } + + is_soap_11 = axis2_msg_ctx_get_is_soap_11(msg_ctx, env); + + /* Set SOAP version */ + axiom_output_set_soap11(request_om_output, env, is_soap_11); + + /* Content-Type */ + if(AXIS2_TRUE == is_soap_11) + { + /* SOAP1.1 */ + content_type = axutil_string_create(env, AXIS2_AMQP_HEADER_ACCEPT_TEXT_XML); + } + else + { + /* SOAP1.2 */ + content_type = axutil_string_create(env, AXIS2_AMQP_HEADER_ACCEPT_APPL_SOAP); + } + + /* SOAP action */ + soap_action = axutil_string_get_buffer(axis2_msg_ctx_get_soap_action(msg_ctx, env), env); + + if(!soap_action) + soap_action = ""; + + /* Handle MTOM */ + do_mtom = axis2_msg_ctx_get_doing_mtom(msg_ctx, env); + + axiom_output_set_do_optimize(request_om_output, env, do_mtom); + axiom_soap_envelope_serialize(request_soap_envelope, env, request_om_output, AXIS2_FALSE); + + if(do_mtom) + { + axis2_status_t mtom_status = AXIS2_FAILURE; + axutil_array_list_t* mime_parts = NULL; + + mtom_status = axiom_output_flush(request_om_output, env); + + if(mtom_status == AXIS2_SUCCESS) + { + mime_parts = axiom_output_get_mime_parts(request_om_output, env); + if(!mime_parts) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Unable to create the mime part list from request_om_output"); + + return AXIS2_FAILURE; + } + else + { + axis2_msg_ctx_set_mime_parts(msg_ctx, env, mime_parts); + } + } + + content_type = axutil_string_create(env, axiom_output_get_content_type(request_om_output, + env)); + } + + request_content = (axis2_char_t*)axiom_xml_writer_get_xml(xml_writer, env); + if(!request_content) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to Serialize the SOAP Envelope"); + return AXIS2_FAILURE; + } + + is_server = axis2_amqp_util_msg_ctx_get_server_side(msg_ctx, env); + + if(is_server) + { + status = axis2_qpid_send(request_content, env, axutil_string_get_buffer(content_type, env), + soap_action, msg_ctx); + } + else + { + if(AXIS2_TRUE == axis2_amqp_util_msg_ctx_get_use_separate_listener(msg_ctx, env)) /* Dual Channel */ + { + status = axis2_qpid_send(request_content, env, axutil_string_get_buffer(content_type, + env), soap_action, msg_ctx); + } + else + { + axis2_op_t* op = NULL; + const axis2_char_t* mep = NULL; + + op = axis2_msg_ctx_get_op(msg_ctx, env); + + if(op) + { + mep = axis2_op_get_msg_exchange_pattern(op, env); + } + + axis2_amqp_response_t* response = NULL; + response = axis2_qpid_send_receive(request_content, env, axutil_string_get_buffer( + content_type, env), soap_action, msg_ctx); + + if(response) + { + /* Create in stream */ + if(response->data) + { + axutil_stream_t* in_stream = NULL; + axutil_property_t* property = NULL; + + in_stream = axutil_stream_create_basic(env); + axutil_stream_write(in_stream, env, response->data, response->length); + + property = axutil_property_create(env); + axutil_property_set_scope(property, env, AXIS2_SCOPE_REQUEST); + axutil_property_set_free_func(property, env, axutil_stream_free_void_arg); + axutil_property_set_value(property, env, in_stream); + + axis2_msg_ctx_set_property(msg_ctx, env, AXIS2_TRANSPORT_IN, property); + } + + if(mep) + { + if(0 == axutil_strcmp(mep, AXIS2_MEP_URI_OUT_IN)) /* Out-In */ + { + axiom_soap_envelope_t* response_soap_envelope = NULL; + + response_soap_envelope = axis2_amqp_util_get_soap_envelope(response, env, + msg_ctx); + if(response_soap_envelope) + { + axis2_msg_ctx_set_response_soap_envelope(msg_ctx, env, + response_soap_envelope); + } + } + } + + status = AXIS2_SUCCESS; + + axis2_msg_ctx_set_status_code(msg_ctx, env, status); + + axis2_amqp_response_free(response, env); + } + else + { + if(mep) + { + if(axutil_strcmp(mep, AXIS2_MEP_URI_OUT_ONLY) == 0 || axutil_strcmp(mep, + AXIS2_MEP_URI_ROBUST_OUT_ONLY) == 0) /* One-way */ + { + status = AXIS2_SUCCESS; + + /* Set status code in msg_ctx */ + axis2_msg_ctx_set_status_code(msg_ctx, env, status); + } + } + } + } + } + + if(content_type) + axutil_string_free(content_type, env); + + return status; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_amqp_sender_clean_up( + axis2_transport_sender_t* sender, + const axutil_env_t* env, + axis2_msg_ctx_t* msg_ctx) +{ + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_amqp_sender_free( + axis2_transport_sender_t* sender, + const axutil_env_t* env) +{ + AXIS2_ENV_CHECK(env, void); + + axis2_amqp_sender_resource_pack_t* sender_resource_pack = NULL; + sender_resource_pack = AXIS2_AMQP_SENDER_TO_RESOURCE_PACK(sender); + + AXIS2_FREE(env->allocator, sender_resource_pack); +} + +/* Library Exports */ + +AXIS2_EXPORT int +#ifndef AXIS2_STATIC_DEPLOY +axis2_get_instance( +#else + axis2_amqp_sender_get_instance( +#endif + struct axis2_transport_sender** inst, + const axutil_env_t* env) +{ + int status = AXIS2_SUCCESS; + + *inst = axis2_amqp_sender_create(env); + if(!(*inst)) + { + status = AXIS2_FAILURE; + } + + return status; +} + +AXIS2_EXPORT int +#ifndef AXIS2_STATIC_DEPLOY +axis2_remove_instance( +#else + axis2_amqp_sender_remove_instance( +#endif + axis2_transport_sender_t* inst, + const axutil_env_t* env) +{ + if(inst) + { + axis2_transport_sender_free(inst, env); + } + + return AXIS2_SUCCESS; +} + diff --git a/src/core/transport/amqp/sender/axis2_amqp_sender.h b/src/core/transport/amqp/sender/axis2_amqp_sender.h new file mode 100644 index 0000000..b523347 --- /dev/null +++ b/src/core/transport/amqp/sender/axis2_amqp_sender.h @@ -0,0 +1,63 @@ +/* + * 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. + */ + +#ifndef AXIS2_AMQP_SENDER_H +#define AXIS2_AMQP_SENDER_H + +#include +#include +#include +#include + +typedef struct axis2_amqp_sender_resource_pack +{ + axis2_transport_sender_t sender; + axis2_conf_ctx_t* conf_ctx; +} +axis2_amqp_sender_resource_pack_t; + +#define AXIS2_AMQP_SENDER_TO_RESOURCE_PACK(amqp_sender) \ + ((axis2_amqp_sender_resource_pack_t*)(amqp_sender)) + +AXIS2_EXTERN axis2_transport_sender_t* AXIS2_CALL +axis2_amqp_sender_create(const axutil_env_t* env); + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_amqp_sender_init( + axis2_transport_sender_t* sender, + const axutil_env_t* env, + axis2_conf_ctx_t* conf_ctx, + axis2_transport_out_desc_t* out_desc); + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_amqp_sender_invoke( + axis2_transport_sender_t* sender, + const axutil_env_t* env, + axis2_msg_ctx_t* msg_ctx); + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_amqp_sender_clean_up( + axis2_transport_sender_t* sender, + const axutil_env_t* env, + axis2_msg_ctx_t* msg_ctx); + +AXIS2_EXTERN void AXIS2_CALL +axis2_amqp_sender_free( + axis2_transport_sender_t* sender, + const axutil_env_t* env); + +#endif diff --git a/src/core/transport/amqp/sender/qpid_sender/Makefile.am b/src/core/transport/amqp/sender/qpid_sender/Makefile.am new file mode 100644 index 0000000..46dcb5e --- /dev/null +++ b/src/core/transport/amqp/sender/qpid_sender/Makefile.am @@ -0,0 +1,23 @@ +lib_LTLIBRARIES = libaxis2_qpid_sender.la + +libaxis2_qpid_sender_la_SOURCES = axis2_qpid_sender.cpp \ + axis2_qpid_sender_interface.cpp + +libaxis2_qpid_sender_la_LIBADD = $(top_builddir)/util/src/libaxutil.la \ + $(top_builddir)/src/core/transport/amqp/util/libaxis2_amqp_util.la \ + $(QPID_HOME)/lib/libqpidclient.la + +libaxis2_qpid_sender_la_LDFLAGS = g++ -version-info $(VERSION_NO) + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/core/transport/amqp/sender/qpid_sender \ + -I$(top_builddir)/src/core/transport/amqp/util \ + -I$(top_builddir)/src/core/description \ + -I$(top_builddir)/src/core/context \ + -I$(top_builddir)/src/core/phaseresolver \ + -I$(top_builddir)/src/core/engine \ + -I$(top_builddir)/src/core/deployment \ + -I$(top_builddir)/util/include \ + -I$(top_builddir)/axiom/include \ + -I$(QPID_HOME)/include + diff --git a/src/core/transport/amqp/sender/qpid_sender/axis2_qpid_sender.cpp b/src/core/transport/amqp/sender/qpid_sender/axis2_qpid_sender.cpp new file mode 100644 index 0000000..7f0799b --- /dev/null +++ b/src/core/transport/amqp/sender/qpid_sender/axis2_qpid_sender.cpp @@ -0,0 +1,242 @@ +/* + * 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 + * + * tcp://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 +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace qpid::client; +using namespace qpid::framing; + +Axis2QpidSender::Axis2QpidSender( + string qpidBrokerIP, + int qpidBrokerPort, + const axutil_env_t* env) +{ + this->qpidBrokerIP = qpidBrokerIP; + this->qpidBrokerPort = qpidBrokerPort; + this->env = env; + this->responseContent = ""; + this->responseContentType = ""; +} + +Axis2QpidSender::~Axis2QpidSender( + void) +{ +} + +bool +Axis2QpidSender::SendReceive( + string messageContent, + string toQueueName, + bool isSOAP11, + string contentType, + string soapAction, + axutil_array_list_t* mime_parts, + int timeout) +{ + bool status = false; + this->responseContent = ""; + this->responseContentType = ""; + + try + { + Connection connection; + connection.open(qpidBrokerIP, qpidBrokerPort); + + Session session = connection.newSession(); + + /* Declare Private Queue */ + string replyToQueueName = AXIS2_AMQP_TEMP_QUEUE_NAME_PREFIX; + replyToQueueName.append(axutil_uuid_gen(env)); + + session.queueDeclare(arg::queue = replyToQueueName, arg::autoDelete = true); + session.exchangeBind(arg::exchange = AXIS2_AMQP_EXCHANGE_DIRECT, arg::queue + = replyToQueueName, arg::bindingKey = replyToQueueName); + + /* Create Message */ + Message reqMessage; + + reqMessage.getDeliveryProperties().setRoutingKey(toQueueName); + reqMessage.getMessageProperties().setReplyTo(ReplyTo(AXIS2_AMQP_EXCHANGE_DIRECT, + replyToQueueName)); + + reqMessage.getHeaders().setString(AXIS2_AMQP_HEADER_CONTENT_TYPE, contentType); + reqMessage.getHeaders().setString(AXIS2_AMQP_HEADER_SOAP_ACTION, soapAction); + + if(mime_parts) + { + string mimeBody; + GetMimeBody(mime_parts, mimeBody); + + messageContent.clear();/* MIME parts include SOAP envelop */ + + messageContent.append(mimeBody); + } + + reqMessage.setData(messageContent); + + session.messageTransfer(arg::content = reqMessage, arg::destination + = AXIS2_AMQP_EXCHANGE_DIRECT); + + /* Create subscription manager */ + SubscriptionManager subscriptionManager(session); + + Message resMessage; + qpid::sys::Duration reqTimeout(timeout * AXIS2_AMQP_NANOSEC_PER_MILLISEC); + + if(subscriptionManager.get(resMessage, replyToQueueName, reqTimeout)) + { + responseContent = resMessage.getData(); + responseContentType = resMessage.getHeaders().getAsString( + AXIS2_AMQP_HEADER_CONTENT_TYPE); + + status = true; + } + + connection.close(); + } + catch(const std::exception& e) + { + } + + return status; +} + +bool +Axis2QpidSender::Send( + string messageContent, + string toQueueName, + string replyToQueueName, + bool isSOAP11, + string contentType, + string soapAction, + axutil_array_list_t* mime_parts) +{ + bool status = false; + + try + { + Connection connection; + connection.open(qpidBrokerIP, qpidBrokerPort); + + Session session = connection.newSession(); + + /* Create Message */ + Message message; + + message.getDeliveryProperties().setRoutingKey(toQueueName); + + if(!replyToQueueName.empty()) /* Client dual-channel */ + { + message.getMessageProperties().setReplyTo(ReplyTo(AXIS2_AMQP_EXCHANGE_DIRECT, + replyToQueueName)); + + session.queueDeclare(arg::queue = replyToQueueName); + session.exchangeBind(arg::exchange = AXIS2_AMQP_EXCHANGE_DIRECT, arg::queue + = replyToQueueName, arg::bindingKey = replyToQueueName); + } + + message.getHeaders().setString(AXIS2_AMQP_HEADER_CONTENT_TYPE, contentType); + message.getHeaders().setString(AXIS2_AMQP_HEADER_SOAP_ACTION, soapAction); + + if(mime_parts) + { + string mimeBody; + GetMimeBody(mime_parts, mimeBody); + + messageContent.clear();/* MIME parts include SOAP envelop */ + + messageContent.append(mimeBody); + } + + message.setData(messageContent); + + session.messageTransfer(arg::content = message, arg::destination + = AXIS2_AMQP_EXCHANGE_DIRECT); + + connection.close(); + + status = true; + } + catch(const std::exception& e) + { + } + + return status; +} + +void +Axis2QpidSender::GetMimeBody( + axutil_array_list_t* mime_parts, + string& mimeBody) +{ + int i = 0; + axiom_mime_part_t *mime_part = NULL; + axis2_status_t status = AXIS2_SUCCESS; + + if(!mime_parts) + return; + + for(i = 0; i < axutil_array_list_size(mime_parts, env); i++) + { + mime_part = (axiom_mime_part_t *)axutil_array_list_get(mime_parts, env, i); + + if(mime_part->type == AXIOM_MIME_PART_BUFFER) + { + mimeBody.append(mime_part->part, mime_part->part_size); + } + else if(mime_part->type == AXIOM_MIME_PART_FILE) + { + int length; + char* buffer; + + ifstream file; + file.open(mime_part->file_name, ios::binary); + + file.seekg(0, ios::end); + length = file.tellg(); + file.seekg(0, ios::beg); + + buffer = new char[length]; + + file.read(buffer, length); + file.close(); + + mimeBody.append(buffer, length); + + delete[] buffer; + } + else + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Unknown mime type"); + return; + } + + if(status == AXIS2_FAILURE) + { + break; + } + } +} diff --git a/src/core/transport/amqp/sender/qpid_sender/axis2_qpid_sender.h b/src/core/transport/amqp/sender/qpid_sender/axis2_qpid_sender.h new file mode 100644 index 0000000..8c94cfa --- /dev/null +++ b/src/core/transport/amqp/sender/qpid_sender/axis2_qpid_sender.h @@ -0,0 +1,49 @@ +/* + * 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 + * + * tcp://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. + */ + +#ifndef AXIS2_QPID_SENDER_H +#define AXIS2_QPID_SENDER_H + +#include +#include +#include + +using std::string; + +class Axis2QpidSender +{ + public: + Axis2QpidSender(string qpidBrokerIP, int qpidBrokerPort, const axutil_env_t* env); + ~Axis2QpidSender(void); + + bool SendReceive(string messageContent, string toQueueName, bool isSOAP11, + string contentType, string soapAction, axutil_array_list_t* mime_parts, int timeout); + bool Send(string messageContent, string toQueueName, string replyToQueueName, bool isSOAP11, + string contentType, string soapAction, axutil_array_list_t* mime_parts); + + string responseContent; + string responseContentType; + + private: + void GetMimeBody(axutil_array_list_t* mime_parts, string& mimeBody); + + string qpidBrokerIP; + int qpidBrokerPort; + const axutil_env_t* env; +}; + +#endif diff --git a/src/core/transport/amqp/sender/qpid_sender/axis2_qpid_sender_interface.cpp b/src/core/transport/amqp/sender/qpid_sender/axis2_qpid_sender_interface.cpp new file mode 100644 index 0000000..ac4f51e --- /dev/null +++ b/src/core/transport/amqp/sender/qpid_sender/axis2_qpid_sender_interface.cpp @@ -0,0 +1,130 @@ +/* +* 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 +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +AXIS2_EXTERN axis2_amqp_response_t* AXIS2_CALL +axis2_qpid_send_receive( + const axis2_char_t* request_content, + const axutil_env_t* env, + const axis2_char_t* content_type, + const axis2_char_t* soap_action, + axis2_msg_ctx_t* msg_ctx) +{ + axis2_amqp_destination_info_t* destination_info = NULL; + destination_info = axis2_amqp_util_msg_ctx_get_destination_info(msg_ctx, env); + + if (!destination_info || !destination_info->broker_ip || + !destination_info->broker_port || !destination_info->queue_name) + { + return NULL; + } + + axis2_bool_t is_soap_11 = axis2_msg_ctx_get_is_soap_11(msg_ctx, env); + axutil_array_list_t* mime_parts = axis2_msg_ctx_get_mime_parts(msg_ctx, env); + int timeout = axis2_amqp_util_msg_ctx_get_request_timeout(msg_ctx, env); + + /* Get Response */ + Axis2QpidSender qpid_sender(destination_info->broker_ip, + destination_info->broker_port, env); + + bool status = qpid_sender.SendReceive(request_content, destination_info->queue_name, + is_soap_11, content_type, soap_action, mime_parts, timeout); + + axis2_amqp_destination_info_free(destination_info, env); + + if (!status) + { + return NULL; + } + + /* Create response */ + axis2_amqp_response_t* response = (axis2_amqp_response_t*)AXIS2_MALLOC( + env->allocator, sizeof(axis2_amqp_response_t)); + + /* Data */ + response->data = AXIS2_MALLOC(env->allocator, qpid_sender.responseContent.size()); + memcpy(response->data, qpid_sender.responseContent.c_str(), + qpid_sender.responseContent.size()); + + /* Length */ + response->length = qpid_sender.responseContent.size(); + + /* ContentType */ + response->content_type = (axis2_char_t*)AXIS2_MALLOC( + env->allocator, qpid_sender.responseContentType.size() + 1); + strcpy(response->content_type, qpid_sender.responseContentType.c_str()); + + return response; +} + + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_qpid_send( + const axis2_char_t* request_content, + const axutil_env_t* env, + const axis2_char_t* content_type, + const axis2_char_t* soap_action, + axis2_msg_ctx_t* msg_ctx) +{ + axis2_amqp_destination_info_t* destination_info = NULL; + axis2_status_t status = AXIS2_FAILURE; + string reply_to_queue_name = ""; + + destination_info = axis2_amqp_util_msg_ctx_get_destination_info(msg_ctx, env); + + if (!destination_info || !destination_info->broker_ip || + !destination_info->broker_port || !destination_info->queue_name) + { + return AXIS2_FAILURE; + } + + axis2_bool_t is_soap_11 = axis2_msg_ctx_get_is_soap_11(msg_ctx, env); + axutil_array_list_t* mime_parts = axis2_msg_ctx_get_mime_parts(msg_ctx, env); + + /* If client side, find reply_to_queue_name */ + if (!axis2_msg_ctx_get_server_side(msg_ctx, env)) + { + axis2_conf_ctx_t* conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + + axis2_char_t* queue_name = + axis2_amqp_util_conf_ctx_get_dual_channel_queue_name(conf_ctx, env); + if (queue_name) + reply_to_queue_name = queue_name; + } + + Axis2QpidSender qpid_sender(destination_info->broker_ip, + destination_info->broker_port, env); + + status = qpid_sender.Send(request_content, destination_info->queue_name, + reply_to_queue_name, is_soap_11, content_type, soap_action, mime_parts); + + axis2_amqp_destination_info_free(destination_info, env); + + return status; +} + +#ifdef __cplusplus +} +#endif diff --git a/src/core/transport/amqp/sender/qpid_sender/axis2_qpid_sender_interface.h b/src/core/transport/amqp/sender/qpid_sender/axis2_qpid_sender_interface.h new file mode 100644 index 0000000..94e232f --- /dev/null +++ b/src/core/transport/amqp/sender/qpid_sender/axis2_qpid_sender_interface.h @@ -0,0 +1,50 @@ +/* +* 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. +*/ + +#ifndef AXIS2_QPID_SENDER_INTERFACE_H +#define AXIS2_QPID_SENDER_INTERFACE_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +AXIS2_EXTERN axis2_amqp_response_t* AXIS2_CALL +axis2_qpid_send_receive( + const axis2_char_t* request_content, + const axutil_env_t* env, + const axis2_char_t* content_type, + const axis2_char_t* soap_action, + axis2_msg_ctx_t* msg_ctx); + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axis2_qpid_send( + const axis2_char_t* request_content, + const axutil_env_t* env, + const axis2_char_t* content_type, + const axis2_char_t* soap_action, + axis2_msg_ctx_t* msg_ctx); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/core/transport/amqp/server/Makefile.am b/src/core/transport/amqp/server/Makefile.am new file mode 100644 index 0000000..2de6967 --- /dev/null +++ b/src/core/transport/amqp/server/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = axis2_amqp_server diff --git a/src/core/transport/amqp/server/axis2_amqp_server/Makefile.am b/src/core/transport/amqp/server/axis2_amqp_server/Makefile.am new file mode 100644 index 0000000..643827f --- /dev/null +++ b/src/core/transport/amqp/server/axis2_amqp_server/Makefile.am @@ -0,0 +1,33 @@ +prgbindir = $(bindir) + +prgbin_PROGRAMS = axis2_amqp_server + +AM_CFLAGS = -g -pthread + +axis2_amqp_server_SOURCES = axis2_amqp_server.c + +axis2_amqp_server_LDADD = $(LDFLAGS) \ + $(top_builddir)/axiom/src/om/libaxis2_axiom.la \ + $(top_builddir)/util/src/libaxutil.la \ + $(top_builddir)/axiom/src/parser/$(WRAPPER_DIR)/libaxis2_parser.la \ + $(top_builddir)/src/core/description/libaxis2_description.la \ + $(top_builddir)/src/core/deployment/libaxis2_deployment.la \ + $(top_builddir)/src/core/context/libaxis2_context.la \ + $(top_builddir)/src/core/clientapi/libaxis2_clientapi.la \ + $(top_builddir)/src/core/engine/libaxis2_engine.la \ + $(top_builddir)/neethi/src/libneethi.la \ + $(top_builddir)/src/core/transport/amqp/receiver/libaxis2_amqp_receiver.la \ + $(top_builddir)/src/core/transport/amqp/util/libaxis2_amqp_util.la \ + -lpthread + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/core/description \ + -I$(top_builddir)/src/core/context \ + -I$(top_builddir)/src/core/deploymenti \ + -I$(top_builddir)/src/core/phaseresolver \ + -I$(top_builddir)/src/core/engine \ + -I$(top_builddir)/src/core/transport/amqp/receiver \ + -I$(top_builddir)/src/core/transport/amqp/receiver/qpid_receiver \ + -I$(top_builddir)/src/core/transport/amqp/util \ + -I$(top_builddir)/util/include \ + -I$(top_builddir)/axiom/include diff --git a/src/core/transport/amqp/server/axis2_amqp_server/axis2_amqp_server.c b/src/core/transport/amqp/server/axis2_amqp_server/axis2_amqp_server.c new file mode 100644 index 0000000..9f69283 --- /dev/null +++ b/src/core/transport/amqp/server/axis2_amqp_server/axis2_amqp_server.c @@ -0,0 +1,232 @@ +/* + * 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 + * + * tcp://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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +axis2_transport_receiver_t* receiver = NULL; +axutil_env_t* server_env = NULL; + +axutil_env_t* +init_server_env( + axutil_allocator_t* allocator, + const axis2_char_t* log_file_name) +{ + axutil_error_t* error = axutil_error_create(allocator); + axutil_log_t* log = axutil_log_create(allocator, NULL, log_file_name); + axutil_thread_pool_t* thread_pool = axutil_thread_pool_init(allocator); + axutil_env_t* env = axutil_env_create_with_error_log_thread_pool(allocator, error, log, + thread_pool); + + axiom_xml_reader_init(); + + return env; +} + +void +server_exit( + int status) +{ + if(receiver) + { + axis2_transport_receiver_free(receiver, server_env); + } + + if(server_env) + { + axutil_env_free(server_env); + } + + axiom_xml_reader_cleanup(); + + exit(status); +} + +void +show_usage( + axis2_char_t* prog_name) +{ + fprintf(stdout, "\n Usage : %s", prog_name); + fprintf(stdout, " [-i QPID_BROKER_IP]"); + fprintf(stdout, " [-p QPID_BROKER_PORT]"); + fprintf(stdout, " [-r REPO_PATH]"); + fprintf(stdout, " [-l LOG_LEVEL]"); + fprintf(stdout, " [-f LOG_FILE]\n"); + fprintf(stdout, " [-s LOG_FILE_SIZE]\n"); + fprintf(stdout, " Options :\n"); + fprintf(stdout, "\t-i QPID_BROKER_IP \t Qpid broker IP, default is 127.0.0.1\n"); + fprintf(stdout, + "\t-p QPID_BROKER_PORT \t the port on which the Qpid broker listens, default is 5672\n"); + fprintf(stdout, "\t-r REPO_PATH \t\t repository path, default is ../\n"); + fprintf(stdout, "\t-l LOG_LEVEL\t\t log level, available log levels:" + "\n\t\t\t\t\t 0 - critical 1 - errors 2 - warnings" + "\n\t\t\t\t\t 3 - information 4 - debug 5- user 6 - trace" + "\n\t\t\t\t\t Default log level is 4(debug).\n"); +#ifndef WIN32 + fprintf(stdout, "\t-f LOG_FILE\t\t log file, default is $AXIS2C_HOME/logs/axis2.log" + "\n\t\t\t\t or axis2.log in current folder if AXIS2C_HOME not set\n"); +#else + fprintf(stdout, + "\t-f LOG_FILE\t\t log file, default is %%AXIS2C_HOME%%\\logs\\axis2.log" + "\n\t\t\t\t or axis2.log in current folder if AXIS2C_HOME not set\n"); +#endif + fprintf(stdout, + "\t-s LOG_FILE_SIZE\t Maximum log file size in mega bytes, default maximum size is 1MB.\n"); + fprintf(stdout, " Help :\n\t-h \t\t\t display this help screen.\n\n"); +} + +#ifndef WIN32 + +void +sig_handler( + int signal) +{ + switch(signal) + { + case SIGINT: + AXIS2_LOG_INFO(server_env->log, "Received signal SIGINT.Server shutting down"); + axis2_amqp_receiver_stop(receiver, server_env); + AXIS2_LOG_INFO(server_env->log, "Shutdown complete ..."); + + server_exit(0); + + case SIGPIPE: + AXIS2_LOG_INFO(server_env->log, "Received signal SIGPIPE.Client request serve aborted"); + return; + + case SIGSEGV: + fprintf(stderr, "Received deadly signal SIGSEGV. Terminating ...\n"); + _exit(-1); + } +} + +#endif + +int +main( + int argc, + char* argv[]) +{ + axutil_allocator_t* allocator = NULL; + extern char* optarg; + extern int optopt; + int c; + const axis2_char_t* qpid_broker_ip = NULL; + int qpid_broker_port = AXIS2_QPID_NULL_CONF_INT; + const axis2_char_t* repo_path = AXIS2_AMQP_SERVER_REPO_PATH; + axutil_log_levels_t log_level = AXIS2_LOG_LEVEL_DEBUG; + const axis2_char_t* log_file_name = AXIS2_AMQP_SERVER_LOG_FILE_NAME; + int log_file_size = AXUTIL_LOG_FILE_SIZE; + + while((c = AXIS2_GETOPT(argc, argv, "i:p:r:l:f:s:h")) != -1) + { + switch(c) + { + case 'i': + qpid_broker_ip = optarg; + break; + + case 'p': + qpid_broker_port = AXIS2_ATOI(optarg); + break; + + case 'r': + repo_path = optarg; + break; + + case 'l': + log_level = AXIS2_ATOI(optarg); + if(log_level < AXIS2_LOG_LEVEL_CRITICAL) + log_level = AXIS2_LOG_LEVEL_CRITICAL; + if(log_level > AXIS2_LOG_LEVEL_TRACE) + log_level = AXIS2_LOG_LEVEL_TRACE; + break; + + case 'f': + log_file_name = optarg; + break; + + case 's': + log_file_size = 1024 * 1024 * AXIS2_ATOI(optarg); + break; + + case 'h': + show_usage(argv[0]); + return 0; + + case ':': + fprintf(stderr, "\nOption -%c requires an operand\n", optopt); + show_usage(argv[0]); + return -1; + + case '?': + if(isprint(optopt)) + fprintf(stderr, "\nUnknown option `-%c'.\n", optopt); + show_usage(argv[0]); + return -1; + } + } + + allocator = axutil_allocator_init(NULL); + if(!allocator) + { + server_exit(-1); + } + + server_env = init_server_env(allocator, log_file_name); + server_env->log->level = log_level; + server_env->log->size = log_file_size; + + axutil_error_init(); + +#ifndef WIN32 + signal(SIGINT, sig_handler); + signal(SIGPIPE, sig_handler); +#endif + + AXIS2_LOG_INFO(server_env->log, "Starting Axis2 AMQP Server ..."); + AXIS2_LOG_INFO(server_env->log, "Repo Location : %s", repo_path); + + receiver = axis2_amqp_receiver_create(server_env, repo_path, qpid_broker_ip, qpid_broker_port); + if(!receiver) + { + AXIS2_LOG_ERROR(server_env->log, AXIS2_LOG_SI, + "Server creation failed: Error code:" " %d :: %s", server_env->error->error_number, + AXIS2_ERROR_GET_MESSAGE(server_env->error)); + server_exit(-1); + } + + if(axis2_amqp_receiver_start(receiver, server_env) == AXIS2_FAILURE) + { + AXIS2_LOG_ERROR(server_env->log, AXIS2_LOG_SI, + "Server start failed: Error code:" " %d :: %s", server_env->error->error_number, + AXIS2_ERROR_GET_MESSAGE(server_env->error)); + server_exit(-1); + } + + return 0; +} diff --git a/src/core/transport/amqp/server/axis2_amqp_server/axis2_amqp_server.h b/src/core/transport/amqp/server/axis2_amqp_server/axis2_amqp_server.h new file mode 100644 index 0000000..82a200e --- /dev/null +++ b/src/core/transport/amqp/server/axis2_amqp_server/axis2_amqp_server.h @@ -0,0 +1,41 @@ +/* + * 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 + * + * tcp://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. + */ + +#ifndef AXIS2_AMQP_SERVER_H +#define AXIS2_AMQP_SERVER_H + +#include +#include + +axutil_env_t* +init_server_env(axutil_allocator_t* allocator, + const axis2_char_t* log_file_name); + +void +server_exit(int status); + +void +show_usage(axis2_char_t* prog_name); + +#ifndef WIN32 + +void +sig_handler(int signal); + +#endif + +#endif diff --git a/src/core/transport/amqp/util/Makefile.am b/src/core/transport/amqp/util/Makefile.am new file mode 100644 index 0000000..2b27d76 --- /dev/null +++ b/src/core/transport/amqp/util/Makefile.am @@ -0,0 +1,18 @@ +lib_LTLIBRARIES = libaxis2_amqp_util.la + +libaxis2_amqp_util_la_SOURCES = axis2_amqp_util.c + +libaxis2_amqp_util_la_LIBADD = $(top_builddir)/util/src/libaxutil.la + +libaxis2_amqp_util_la_LDFLAGS = -version-info $(VERSION_NO) + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/src/core/transport/amqp/util \ + -I$(top_builddir)/src/core/transport/amqp/sender/qpid_sender \ + -I$(top_builddir)/src/core/description \ + -I$(top_builddir)/src/core/context \ + -I$(top_builddir)/src/core/engine \ + -I$(top_builddir)/src/core/deployment \ + -I$(top_builddir)/util/include \ + -I$(top_builddir)/axiom/include + diff --git a/src/core/transport/amqp/util/axis2_amqp_defines.h b/src/core/transport/amqp/util/axis2_amqp_defines.h new file mode 100644 index 0000000..a892e9e --- /dev/null +++ b/src/core/transport/amqp/util/axis2_amqp_defines.h @@ -0,0 +1,65 @@ +/* + * 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. + */ + +#ifndef AXIS2_AMQP_DEFINES_H +#define AXIS2_AMQP_DEFINES_H + +#include + +#define AXIS2_AMQP_EXCHANGE_DIRECT "amq.direct" + +#define AXIS2_AMQP_CONF_QPID_BROKER_IP "qpid_broker_ip" +#define AXIS2_AMQP_CONF_QPID_BROKER_PORT "qpid_broker_port" +#define AXIS2_AMQP_CONF_QPID_REQUEST_TIMEOUT "request_timeout" + +#define AXIS2_QPID_DEFAULT_BROKER_IP "127.0.0.1" +#define AXIS2_QPID_DEFAULT_BROKER_PORT 5672 +#define AXIS2_QPID_DEFAULT_REQUEST_TIMEOUT 500 +#define AXIS2_QPID_NULL_CONF_INT -1 + +#define AXIS2_AMQP_CONF_CTX_PROPERTY_BROKER_IP "qpid_broker_ip" +#define AXIS2_AMQP_CONF_CTX_PROPERTY_BROKER_PORT "qpid_broker_port" +#define AXIS2_AMQP_CONF_CTX_PROPERTY_REQUEST_TIMEOUT "request_timeout" +#define AXIS2_AMQP_CONF_CTX_PROPERTY_QUEUE_NAME "queue_name" + +#define AXIS2_AMQP_MSG_CTX_PROPERTY_REPLY_TO "qpid_reply_to" + +#define AXIS2_AMQP_HEADER_ACCEPT_TEXT_XML "text/xml" +#define AXIS2_AMQP_HEADER_ACCEPT_APPL_SOAP "application/soap+xml" +#define AXIS2_AMQP_HEADER_ACCEPT_MULTIPART_RELATED AXIOM_MIME_TYPE_MULTIPART_RELATED +#define AXIS2_AMQP_HEADER_CONTENT_TYPE_MIME_BOUNDARY "boundary" +#define AXIS2_AMQP_HEADER_SOAP_ACTION "SOAPAction" +#define AXIS2_AMQP_HEADER_CONTENT_TYPE "Content-Type" + +#define AXIS2_AMQP_TEMP_QUEUE_NAME_PREFIX "TempQueue" + +#define AXIS2_AMQP_SERVER_LOG_FILE_NAME "axis2_amqp_server.log" +#define AXIS2_AMQP_SERVER_REPO_PATH "../" + +#define AXIS2_AMQP_EPR_PREFIX "amqp:" +#define AXIS2_AMQP_EPR_SERVICE_PREFIX "services" +#define AXIS2_AMQP_EPR_ANON_SERVICE_NAME "__ANONYMOUS_SERVICE__" + +#define AXIS2_AMQP_EQ '=' +#define AXIS2_AMQP_SEMI_COLON ';' +#define AXIS2_AMQP_ESC_NULL '\0' +#define AXIS2_AMQP_DOUBLE_QUOTE '"' +#define AXIS2_AMQP_B_SLASH '\\' + +#define AXIS2_AMQP_NANOSEC_PER_MILLISEC 1000*1000 + +#endif diff --git a/src/core/transport/amqp/util/axis2_amqp_util.c b/src/core/transport/amqp/util/axis2_amqp_util.c new file mode 100644 index 0000000..cfef4a9 --- /dev/null +++ b/src/core/transport/amqp/util/axis2_amqp_util.c @@ -0,0 +1,823 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include + +AXIS2_EXTERN axis2_char_t* AXIS2_CALL +axis2_amqp_util_get_in_desc_conf_value_string( + axis2_transport_in_desc_t* in_desc, + const axutil_env_t* env, + const axis2_char_t* param_name) +{ + axutil_param_t* param = NULL; + axis2_char_t* value = NULL; + + param = (axutil_param_t*)axutil_param_container_get_param( + axis2_transport_in_desc_param_container(in_desc, env), env, param_name); + if(param) + { + value = axutil_param_get_value(param, env); + } + + return value; +} + +AXIS2_EXTERN int AXIS2_CALL +axis2_amqp_util_get_in_desc_conf_value_int( + axis2_transport_in_desc_t* in_desc, + const axutil_env_t* env, + const axis2_char_t* param_name) +{ + axis2_char_t* value_str = NULL; + int value = AXIS2_QPID_NULL_CONF_INT; + + value_str = axis2_amqp_util_get_in_desc_conf_value_string(in_desc, env, param_name); + if(value_str) + { + value = atoi(value_str); + } + + return value; +} + +AXIS2_EXTERN axis2_char_t* AXIS2_CALL +axis2_amqp_util_get_out_desc_conf_value_string( + axis2_transport_out_desc_t* out_desc, + const axutil_env_t* env, + const axis2_char_t* param_name) +{ + axutil_param_t* param = NULL; + axis2_char_t* value = NULL; + + param = (axutil_param_t*)axutil_param_container_get_param( + axis2_transport_out_desc_param_container(out_desc, env), env, param_name); + if(param) + { + value = axutil_param_get_value(param, env); + } + + return value; +} + +AXIS2_EXTERN int AXIS2_CALL +axis2_amqp_util_get_out_desc_conf_value_int( + axis2_transport_out_desc_t* out_desc, + const axutil_env_t* env, + const axis2_char_t* param_name) +{ + axis2_char_t* value_str = NULL; + int value = AXIS2_QPID_NULL_CONF_INT; + + value_str = axis2_amqp_util_get_out_desc_conf_value_string(out_desc, env, param_name); + if(value_str) + { + value = atoi(value_str); + } + + return value; +} + +AXIS2_EXTERN axiom_soap_envelope_t* AXIS2_CALL +axis2_amqp_util_get_soap_envelope( + axis2_amqp_response_t* response, + const axutil_env_t* env, + axis2_msg_ctx_t* msg_ctx) +{ + axiom_xml_reader_t* xml_reader = NULL; + axiom_stax_builder_t* stax_builder = NULL; + axiom_soap_builder_t* soap_builder = NULL; + axiom_soap_envelope_t* soap_envelope = NULL; + const axis2_char_t* soap_ns_uri = NULL; + axis2_char_t *soap_body_str = NULL; + int soap_body_len = 0; + axis2_bool_t is_mtom = AXIS2_FALSE; + axutil_hash_t *binary_data_map = NULL; + axis2_bool_t is_soap_11 = AXIS2_FALSE; + + if(!response || !response->data || !response->content_type) + { + return NULL; + } + + is_soap_11 = axis2_msg_ctx_get_is_soap_11(msg_ctx, env); + + /* Handle MTOM */ + if(strstr(response->content_type, AXIS2_AMQP_HEADER_ACCEPT_MULTIPART_RELATED)) + { + axis2_char_t* mime_boundary = axis2_amqp_util_get_value_from_content_type(env, + response->content_type, AXIS2_AMQP_HEADER_CONTENT_TYPE_MIME_BOUNDARY); + + if(mime_boundary) + { + axiom_mime_parser_t *mime_parser = NULL; + int soap_body_len = 0; + axutil_param_t *buffer_size_param = NULL; + axutil_param_t *max_buffers_param = NULL; + axutil_param_t *attachment_dir_param = NULL; + axis2_char_t *value_size = NULL; + axis2_char_t *value_num = NULL; + axis2_char_t *value_dir = NULL; + int size = 0; + int num = 0; + + mime_parser = axiom_mime_parser_create(env); + + buffer_size_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_MTOM_BUFFER_SIZE); + + if(buffer_size_param) + { + value_size = (axis2_char_t *)axutil_param_get_value(buffer_size_param, env); + + if(value_size) + { + size = atoi(value_size); + axiom_mime_parser_set_buffer_size(mime_parser, env, size); + } + } + + max_buffers_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_MTOM_MAX_BUFFERS); + + if(max_buffers_param) + { + value_num = (axis2_char_t*)axutil_param_get_value(max_buffers_param, env); + + if(value_num) + { + num = atoi(value_num); + axiom_mime_parser_set_max_buffers(mime_parser, env, num); + } + } + + attachment_dir_param = axis2_msg_ctx_get_parameter(msg_ctx, env, AXIS2_ATTACHMENT_DIR); + + if(attachment_dir_param) + { + value_dir = (axis2_char_t*)axutil_param_get_value(attachment_dir_param, env); + + if(value_dir) + { + axiom_mime_parser_set_attachment_dir(mime_parser, env, value_dir); + } + } + + if(mime_parser) + { + axis2_callback_info_t* callback_ctx = NULL; + axutil_stream_t* stream = NULL; + + callback_ctx = (axis2_callback_info_t*)AXIS2_MALLOC(env->allocator, + sizeof(axis2_callback_info_t)); + + stream = axutil_stream_create_basic(env); + + if(stream) + { + axutil_stream_write(stream, env, response->data, response->length); + callback_ctx->env = env; + callback_ctx->in_stream = stream; + callback_ctx->content_length = response->length; + callback_ctx->unread_len = response->length; + callback_ctx->chunked_stream = NULL; + } + + /*binary_data_map = + axiom_mime_parser_parse(mime_parser, env, + axis2_amqp_util_on_data_request, + (void*)callback_ctx, + mime_boundary);*/ + + if(!binary_data_map) + { + return AXIS2_FAILURE; + } + + soap_body_len = axiom_mime_parser_get_soap_body_len(mime_parser, env); + + soap_body_str = axiom_mime_parser_get_soap_body_str(mime_parser, env); + + axutil_stream_free(stream, env); + AXIS2_FREE(env->allocator, callback_ctx); + axiom_mime_parser_free(mime_parser, env); + } + + AXIS2_FREE(env->allocator, mime_boundary); + } + + is_mtom = AXIS2_TRUE; + } + else + { + soap_body_str = response->data; + soap_body_len = axutil_strlen(response->data); + } + + soap_body_len = axutil_strlen(soap_body_str); + + xml_reader = axiom_xml_reader_create_for_memory(env, soap_body_str, soap_body_len, NULL, + AXIS2_XML_PARSER_TYPE_BUFFER); + if(!xml_reader) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to Create XML Reader"); + return NULL; + } + + stax_builder = axiom_stax_builder_create(env, xml_reader); + if(!stax_builder) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to Create StAX Builder"); + return NULL; + } + + soap_ns_uri = is_soap_11 ? AXIOM_SOAP11_SOAP_ENVELOPE_NAMESPACE_URI + : AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI; + + soap_builder = axiom_soap_builder_create(env, stax_builder, soap_ns_uri); + if(!soap_builder) + { + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to Create SOAP Builder"); + return NULL; + } + + if(binary_data_map) + { + axiom_soap_builder_set_mime_body_parts(soap_builder, env, binary_data_map); + } + + soap_envelope = axiom_soap_builder_get_soap_envelope(soap_builder, env); + + if(soap_envelope) + { + /* hack to get around MTOM problem */ + axiom_soap_body_t *soap_body = axiom_soap_envelope_get_body(soap_envelope, env); + + if(soap_body) + { + axiom_soap_body_has_fault(soap_body, env); + } + } + + return soap_envelope; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_amqp_util_conf_ctx_get_server_side( + axis2_conf_ctx_t* conf_ctx, + const axutil_env_t* env) +{ + axutil_property_t* property = NULL; + axis2_char_t* value = NULL; + + property = axis2_conf_ctx_get_property(conf_ctx, env, AXIS2_IS_SVR_SIDE); + if(!property) + return AXIS2_TRUE; + + value = (axis2_char_t*)axutil_property_get_value(property, env); + if(!value) + return AXIS2_TRUE; + + return (axutil_strcmp(value, AXIS2_VALUE_TRUE) == 0) ? AXIS2_TRUE : AXIS2_FALSE; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axis2_amqp_util_get_value_from_content_type( + const axutil_env_t * env, + const axis2_char_t * content_type, + const axis2_char_t * key) +{ + axis2_char_t *tmp = NULL; + axis2_char_t *tmp_content_type = NULL; + axis2_char_t *tmp2 = NULL; + + AXIS2_PARAM_CHECK(env->error, content_type, NULL); + AXIS2_PARAM_CHECK(env->error, key, NULL); + + tmp_content_type = axutil_strdup(env, content_type); + + if(!tmp_content_type) + { + return NULL; + } + + tmp = strstr(tmp_content_type, key); + + if(!tmp) + { + AXIS2_FREE(env->allocator, tmp_content_type); + return NULL; + } + + tmp = strchr(tmp, AXIS2_AMQP_EQ); + tmp2 = strchr(tmp, AXIS2_AMQP_SEMI_COLON); + + if(tmp2) + { + *tmp2 = AXIS2_AMQP_ESC_NULL; + } + + if(!tmp) + { + AXIS2_FREE(env->allocator, tmp_content_type); + return NULL; + } + + tmp2 = axutil_strdup(env, tmp + 1); + + AXIS2_FREE(env->allocator, tmp_content_type); + + if(*tmp2 == AXIS2_AMQP_DOUBLE_QUOTE) + { + tmp = tmp2; + tmp2 = axutil_strdup(env, tmp + 1); + tmp2[strlen(tmp2) - 1] = AXIS2_AMQP_ESC_NULL; + + if(tmp) + { + AXIS2_FREE(env->allocator, tmp); + tmp = NULL; + } + } + + /* handle XOP */ + if(*tmp2 == AXIS2_AMQP_B_SLASH && *(tmp2 + 1) == '\"') + { + tmp = tmp2; + tmp2 = axutil_strdup(env, tmp + 2); + tmp2[strlen(tmp2) - 3] = AXIS2_AMQP_ESC_NULL; + + if(tmp) + { + AXIS2_FREE(env->allocator, tmp); + tmp = NULL; + } + } + + return tmp2; +} + +AXIS2_EXTERN int AXIS2_CALL +axis2_amqp_util_on_data_request( + char* buffer, + int size, + void* ctx) +{ + const axutil_env_t* env = NULL; + int len = -1; + axis2_callback_info_t* cb_ctx = (axis2_callback_info_t*)ctx; + axutil_stream_t* in_stream = NULL; + + if(!buffer || !ctx) + { + return 0; + } + + if(cb_ctx->unread_len <= 0 && -1 != cb_ctx->content_length) + { + return 0; + } + + env = ((axis2_callback_info_t*)ctx)->env; + + in_stream = (axutil_stream_t*)((axis2_callback_info_t *)ctx)->in_stream; + --size; /* reserve space to insert trailing null */ + + len = axutil_stream_read(in_stream, env, buffer, size); + + if(len > 0) + { + buffer[len] = AXIS2_AMQP_ESC_NULL; + ((axis2_callback_info_t*)ctx)->unread_len -= len; + } + else if(len == 0) + { + ((axis2_callback_info_t*)ctx)->unread_len = 0; + } + + return len; +} + +AXIS2_EXTERN axis2_char_t* AXIS2_CALL +axis2_amqp_util_conf_ctx_get_dual_channel_queue_name( + axis2_conf_ctx_t* conf_ctx, + const axutil_env_t* env) +{ + axutil_property_t* property = NULL; + axis2_char_t* queue_name = NULL; + axis2_char_t* value = NULL; + + /* Get property */ + property = axis2_conf_ctx_get_property(conf_ctx, env, AXIS2_AMQP_CONF_CTX_PROPERTY_QUEUE_NAME); + if(!property) /* Very first call */ + { + property = axutil_property_create(env); + + axis2_conf_ctx_set_property(conf_ctx, env, AXIS2_AMQP_CONF_CTX_PROPERTY_QUEUE_NAME, + property); + } + + /* Get queue name */ + value = (axis2_char_t*)axutil_property_get_value(property, env); + + /* AMQP listener and the sender are the two parties that are + * interested in the queue. Either party can create the queue. + * If the queue is already created by one party, "value" is + * not NULL. If "value" is NULL, that mean the caller of + * this method is supposed to create the queue */ + if(value) + { + queue_name = (axis2_char_t*)AXIS2_MALLOC(env->allocator, axutil_strlen(value) + 1); + strcpy(queue_name, value); + + /*axutil_property_set_value(property, env, NULL);*/ + } + else + { + /* Create new queue name */ + queue_name = axutil_stracat(env, AXIS2_AMQP_TEMP_QUEUE_NAME_PREFIX, axutil_uuid_gen(env)); + + /* Put queue name in the conf_ctx so that the sender will know */ + axutil_property_set_value(property, env, (void*)queue_name); + } + + return queue_name; +} + +AXIS2_EXTERN axis2_char_t* AXIS2_CALL +axis2_amqp_util_conf_ctx_get_qpid_broker_ip( + axis2_conf_ctx_t* conf_ctx, + const axutil_env_t* env) +{ + axutil_property_t* property = NULL; + void* value = NULL; + axis2_char_t* broker_ip = AXIS2_QPID_DEFAULT_BROKER_IP; + + property = axis2_conf_ctx_get_property(conf_ctx, env, AXIS2_AMQP_CONF_CTX_PROPERTY_BROKER_IP); + + if(property) + { + value = axutil_property_get_value(property, env); + + if(value) + { + broker_ip = (axis2_char_t*)value; + } + } + + return broker_ip; +} + +AXIS2_EXTERN int AXIS2_CALL +axis2_amqp_util_conf_ctx_get_qpid_broker_port( + axis2_conf_ctx_t* conf_ctx, + const axutil_env_t* env) +{ + axutil_property_t* property = NULL; + void* value = NULL; + int broker_port = AXIS2_QPID_DEFAULT_BROKER_PORT; + + property = axis2_conf_ctx_get_property(conf_ctx, env, AXIS2_AMQP_CONF_CTX_PROPERTY_BROKER_PORT); + + if(property) + { + value = axutil_property_get_value(property, env); + + if(value) + { + broker_port = *(int*)value; + } + } + + return broker_port; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_amqp_util_msg_ctx_get_use_separate_listener( + axis2_msg_ctx_t* msg_ctx, + const axutil_env_t* env) +{ + axutil_property_t* property = NULL; + axis2_char_t* value = NULL; + axis2_bool_t use_separate_listener = AXIS2_FALSE; + + property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_USE_SEPARATE_LISTENER); + + if(property) + { + value = (axis2_char_t*)axutil_property_get_value(property, env); + + if(value && (axutil_strcmp(AXIS2_VALUE_TRUE, value) == 0)) + { + use_separate_listener = AXIS2_TRUE; + } + } + + return use_separate_listener; +} + +AXIS2_EXTERN axis2_amqp_destination_info_t* AXIS2_CALL +axis2_amqp_util_msg_ctx_get_destination_info( + axis2_msg_ctx_t* msg_ctx, + const axutil_env_t* env) +{ + /* The destination URI that is expected by this method + * should be of one of the following formats + * 1. amqp://IP:PORT/services/SERVICE_NAME + * 2. jms:/SERVICE_NAME?java.naming.provider.url=tcp://IP:PORT... + * 3. TempQueue... */ + + axis2_endpoint_ref_t* endpoint_ref = NULL; + axis2_amqp_destination_info_t* destination_info = NULL; + + destination_info = (axis2_amqp_destination_info_t*)AXIS2_MALLOC(env->allocator, + sizeof(axis2_amqp_destination_info_t)); + + destination_info->broker_ip = NULL; + destination_info->broker_port = AXIS2_QPID_NULL_CONF_INT; + destination_info->queue_name = NULL; + + endpoint_ref = axis2_msg_ctx_get_to(msg_ctx, env); + + if(endpoint_ref) + { + const axis2_char_t* endpoint_address_original = NULL; + axis2_char_t* endpoint_address = NULL; + char* substr = NULL; + char* token = NULL; + endpoint_address_original = axis2_endpoint_ref_get_address(endpoint_ref, env); + + if(!endpoint_address_original) + return NULL; + + endpoint_address = (axis2_char_t*)AXIS2_MALLOC(env->allocator, (sizeof(axis2_char_t) + * axutil_strlen(endpoint_address_original)) + 1); + strcpy((char*)endpoint_address, (char*)endpoint_address_original); + + if((substr = strstr(endpoint_address, AXIS2_AMQP_EPR_PREFIX))) /* Start with amqp: */ + { + if(strstr(endpoint_address, AXIS2_AMQP_EPR_ANON_SERVICE_NAME)) + { + /* Server reply to dual-channel client */ + axutil_property_t* property = NULL; + property = axis2_msg_ctx_get_property(msg_ctx, env, + AXIS2_AMQP_MSG_CTX_PROPERTY_REPLY_TO); + + if(property) + { + axis2_char_t* queue_name = (axis2_char_t*)axutil_property_get_value(property, + env); + + if(queue_name) + { + destination_info->queue_name = (axis2_char_t*)AXIS2_MALLOC(env->allocator, + (sizeof(axis2_char_t) * strlen(queue_name)) + 1); + strcpy(destination_info->queue_name, queue_name); + } + } + } + else + { + substr += strlen(AXIS2_AMQP_EPR_PREFIX) + 2; /* 2 -> "//" */ + if(substr) /* IP:PORT/services/SERVICE_NAME */ + { + token = strtok(substr, ":"); + if(token) /* IP */ + { + axis2_char_t* broker_ip = (axis2_char_t*)AXIS2_MALLOC(env->allocator, + (sizeof(axis2_char_t) * strlen(token)) + 1); + strcpy(broker_ip, token); + destination_info->broker_ip = broker_ip; + + token = strtok(NULL, "/"); /* PORT */ + if(token) + { + destination_info->broker_port = atoi(token); + + token = strtok(NULL, "#"); /* ... services/SERVICE_NAME */ + if(token) + { + if((substr = strstr(token, AXIS2_AMQP_EPR_SERVICE_PREFIX))) + { + substr += strlen(AXIS2_AMQP_EPR_SERVICE_PREFIX) + 1; /* 1 -> "/" */ + if(substr) + { + axis2_char_t* queue_name = (axis2_char_t*)AXIS2_MALLOC( + env->allocator, (sizeof(axis2_char_t) * strlen(substr)) + + 1); + strcpy(queue_name, substr); + destination_info->queue_name = queue_name; + } + } + } + } + } + } + } + } + else if(0 == strcmp(endpoint_address, AXIS2_WSA_ANONYMOUS_URL)) /* Required to work with Sandesha2 */ + { + axutil_property_t* property = NULL; + property = axis2_msg_ctx_get_property(msg_ctx, env, + AXIS2_AMQP_MSG_CTX_PROPERTY_REPLY_TO); + + if(property) + { + axis2_char_t* queue_name = (axis2_char_t*)axutil_property_get_value(property, env); + + if(queue_name) + { + destination_info->queue_name = (axis2_char_t*)AXIS2_MALLOC(env->allocator, + (sizeof(axis2_char_t) * strlen(queue_name)) + 1); + strcpy(destination_info->queue_name, queue_name); + } + } + } + else if((substr = strstr(endpoint_address, "jms:/")) && (substr == endpoint_address)) + { + + } + + AXIS2_FREE(env->allocator, endpoint_address); + } + else + { + /* Single-channel blocking */ + axutil_property_t* property = NULL; + property = axis2_msg_ctx_get_property(msg_ctx, env, AXIS2_AMQP_MSG_CTX_PROPERTY_REPLY_TO); + + if(property) + { + axis2_char_t* queue_name = (axis2_char_t*)axutil_property_get_value(property, env); + + if(queue_name) + { + destination_info->queue_name = (axis2_char_t*)AXIS2_MALLOC(env->allocator, + (sizeof(axis2_char_t) * strlen(queue_name)) + 1); + strcpy(destination_info->queue_name, queue_name); + } + } + } + + /* Get broker IP/Port from conf_ctx if they are not + * found in the destination URI */ + if(!destination_info->broker_ip) + { + axis2_conf_ctx_t* conf_ctx = NULL; + + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + if(conf_ctx) + { + axutil_property_t* property = NULL; + property = axis2_conf_ctx_get_property(conf_ctx, env, + AXIS2_AMQP_CONF_CTX_PROPERTY_BROKER_IP); + + if(property) + { + axis2_char_t* broker_ip = (axis2_char_t*)axutil_property_get_value(property, env); + + if(broker_ip) + { + destination_info->broker_ip = (axis2_char_t*)AXIS2_MALLOC(env->allocator, + (sizeof(axis2_char_t) * strlen(broker_ip)) + 1); + strcpy(destination_info->broker_ip, broker_ip); + } + } + + } + } + + if(AXIS2_QPID_NULL_CONF_INT == destination_info->broker_port) + { + axis2_conf_ctx_t* conf_ctx = NULL; + + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + if(conf_ctx) + { + axutil_property_t* property = NULL; + property = axis2_conf_ctx_get_property(conf_ctx, env, + AXIS2_AMQP_CONF_CTX_PROPERTY_BROKER_PORT); + + if(property) + { + void* value = axutil_property_get_value(property, env); + + if(value) + { + destination_info->broker_port = *(int*)value; + } + } + } + } + + return destination_info; +} + +AXIS2_EXTERN int AXIS2_CALL +axis2_amqp_util_msg_ctx_get_request_timeout( + axis2_msg_ctx_t* msg_ctx, + const axutil_env_t* env) +{ + axis2_conf_ctx_t* conf_ctx = NULL; + axutil_property_t* property = NULL; + void* value = NULL; + int request_timeout = AXIS2_QPID_DEFAULT_REQUEST_TIMEOUT; + + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + + if(conf_ctx) + { + property = axis2_conf_ctx_get_property(conf_ctx, env, + AXIS2_AMQP_CONF_CTX_PROPERTY_REQUEST_TIMEOUT); + + if(property) + { + value = axutil_property_get_value(property, env); + + if(value) + { + request_timeout = *(int*)value; + } + } + } + + return request_timeout; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axis2_amqp_util_msg_ctx_get_server_side( + axis2_msg_ctx_t* msg_ctx, + const axutil_env_t* env) +{ + axis2_conf_ctx_t* conf_ctx = NULL; + axis2_bool_t is_server = AXIS2_FALSE; + + conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + + if(conf_ctx) + { + is_server = axis2_amqp_util_conf_ctx_get_server_side(conf_ctx, env); + } + + return is_server; +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_amqp_response_free( + axis2_amqp_response_t* response, + const axutil_env_t* env) +{ + if(response) + { + if(response->data) + { + AXIS2_FREE(env->allocator, response->data); + } + + if(response->content_type) + { + AXIS2_FREE(env->allocator, response->content_type); + } + + AXIS2_FREE(env->allocator, response); + } +} + +AXIS2_EXTERN void AXIS2_CALL +axis2_amqp_destination_info_free( + axis2_amqp_destination_info_t* destination_info, + const axutil_env_t* env) +{ + if(destination_info) + { + if(destination_info->broker_ip) + { + AXIS2_FREE(env->allocator, destination_info->broker_ip); + } + + if(destination_info->queue_name) + { + AXIS2_FREE(env->allocator, destination_info->queue_name); + } + + AXIS2_FREE(env->allocator, destination_info); + } +} + diff --git a/src/core/transport/amqp/util/axis2_amqp_util.h b/src/core/transport/amqp/util/axis2_amqp_util.h new file mode 100644 index 0000000..0b3abbb --- /dev/null +++ b/src/core/transport/amqp/util/axis2_amqp_util.h @@ -0,0 +1,143 @@ +/* + * 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. + */ + +#ifndef AXIS2_AMQP_UTIL_H +#define AXIS2_AMQP_UTIL_H + +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + typedef struct axis2_amqp_response + { + void* data; + int length; + axis2_char_t* content_type; + } axis2_amqp_response_t; + + typedef struct axis2_amqp_destination_info + { + axis2_char_t* broker_ip; + int broker_port; + axis2_char_t* queue_name; + } axis2_amqp_destination_info_t; + + AXIS2_EXTERN axis2_char_t* AXIS2_CALL + axis2_amqp_util_get_in_desc_conf_value_string( + axis2_transport_in_desc_t* in_desc, + const axutil_env_t* env, + const axis2_char_t* param_name); + + AXIS2_EXTERN int AXIS2_CALL + axis2_amqp_util_get_in_desc_conf_value_int( + axis2_transport_in_desc_t* in_desc, + const axutil_env_t* env, + const axis2_char_t* param_name); + + AXIS2_EXTERN axis2_char_t* AXIS2_CALL + axis2_amqp_util_get_out_desc_conf_value_string( + axis2_transport_out_desc_t* out_desc, + const axutil_env_t* env, + const axis2_char_t* param_name); + + AXIS2_EXTERN int AXIS2_CALL + axis2_amqp_util_get_out_desc_conf_value_int( + axis2_transport_out_desc_t* out_desc, + const axutil_env_t* env, + const axis2_char_t* param_name); + + AXIS2_EXTERN axiom_soap_envelope_t* AXIS2_CALL + axis2_amqp_util_get_soap_envelope( + axis2_amqp_response_t* response, + const axutil_env_t* env, + axis2_msg_ctx_t* msg_ctx); + + AXIS2_EXTERN axis2_bool_t AXIS2_CALL + axis2_amqp_util_conf_ctx_get_server_side( + axis2_conf_ctx_t* conf_ctx, + const axutil_env_t* env); + + AXIS2_EXTERN axis2_char_t* AXIS2_CALL + axis2_amqp_util_get_value_from_content_type( + const axutil_env_t * env, + const axis2_char_t * content_type, + const axis2_char_t * key); + + AXIS2_EXTERN int AXIS2_CALL + axis2_amqp_util_on_data_request( + char *buffer, + int size, + void *ctx); + + AXIS2_EXTERN axis2_char_t* AXIS2_CALL + axis2_amqp_util_conf_ctx_get_dual_channel_queue_name( + axis2_conf_ctx_t* conf_ctx, + const axutil_env_t* env); + + AXIS2_EXTERN axis2_char_t* AXIS2_CALL + axis2_amqp_util_conf_ctx_get_qpid_broker_ip( + axis2_conf_ctx_t* conf_ctx, + const axutil_env_t* env); + + AXIS2_EXTERN int AXIS2_CALL + axis2_amqp_util_conf_ctx_get_qpid_broker_port( + axis2_conf_ctx_t* conf_ctx, + const axutil_env_t* env); + + AXIS2_EXTERN axis2_bool_t AXIS2_CALL + axis2_amqp_util_msg_ctx_get_use_separate_listener( + axis2_msg_ctx_t* msg_ctx, + const axutil_env_t* env); + + AXIS2_EXTERN axis2_amqp_destination_info_t* AXIS2_CALL + axis2_amqp_util_msg_ctx_get_destination_info( + axis2_msg_ctx_t* msg_ctx, + const axutil_env_t* env); + + AXIS2_EXTERN int AXIS2_CALL + axis2_amqp_util_msg_ctx_get_request_timeout( + axis2_msg_ctx_t* msg_ctx, + const axutil_env_t* env); + + AXIS2_EXTERN axis2_bool_t AXIS2_CALL + axis2_amqp_util_msg_ctx_get_server_side( + axis2_msg_ctx_t* msg_ctx, + const axutil_env_t* env); + + AXIS2_EXTERN void AXIS2_CALL + axis2_amqp_response_free( + axis2_amqp_response_t* response, + const axutil_env_t* env); + + AXIS2_EXTERN void AXIS2_CALL + axis2_amqp_destination_info_free( + axis2_amqp_destination_info_t* destination_info, + const axutil_env_t* env); + +#ifdef __cplusplus +} +#endif + +#endif -- cgit v1.1-32-gdbae