diff options
Diffstat (limited to 'sca-cpp/branches/cpp-contrib/components/webservice')
17 files changed, 1344 insertions, 0 deletions
diff --git a/sca-cpp/branches/cpp-contrib/components/webservice/Makefile.am b/sca-cpp/branches/cpp-contrib/components/webservice/Makefile.am new file mode 100644 index 0000000000..264b150c93 --- /dev/null +++ b/sca-cpp/branches/cpp-contrib/components/webservice/Makefile.am @@ -0,0 +1,54 @@ +# 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. + +if WANT_WEBSERVICE + +noinst_PROGRAMS = axiom-test axis2-test client-test + +INCLUDES = -I${AXIS2C_INCLUDE} + +compdir=$(prefix)/components/webservice +comp_LTLIBRARIES = libwebservice-client.la libwebservice-listener.la libaxis2-dispatcher.la libaxis2-service.la +comp_DATA = axis2c.prefix + +libwebservice_client_la_SOURCES = webservice-client.cpp +libwebservice_client_la_LDFLAGS = -lxml2 -L${AXIS2C_LIB} -R${AXIS2C_LIB} -laxis2_engine + +libwebservice_listener_la_SOURCES = webservice-listener.cpp +libwebservice_listener_la_LDFLAGS = -lxml2 -L${AXIS2C_LIB} -R${AXIS2C_LIB} -laxis2_engine + +libaxis2_dispatcher_la_SOURCES = axis2-dispatcher.cpp +libaxis2_dispatcher_la_LDFLAGS = -lxml2 -L${AXIS2C_LIB} -R${AXIS2C_LIB} -laxis2_engine + +libaxis2_service_la_SOURCES = axis2-service.cpp +libaxis2_service_la_LDFLAGS = -lxml2 -L${AXIS2C_LIB} -R${AXIS2C_LIB} -laxis2_engine + +axiom_test_SOURCES = axiom-test.cpp +axiom_test_LDFLAGS = -lxml2 -L${AXIS2C_LIB} -R${AXIS2C_LIB} -laxis2_engine + +axis2_test_SOURCES = axis2-test.cpp +axis2_test_LDFLAGS = -lxml2 -L${AXIS2C_LIB} -R${AXIS2C_LIB} -laxis2_engine + +client_test_SOURCES = client-test.cpp +client_test_LDFLAGS = -lxml2 -lcurl -lmozjs -L${AXIS2C_LIB} -R${AXIS2C_LIB} -laxis2_engine + +axis2c.prefix: $(top_builddir)/config.status + echo ${AXIS2C_PREFIX} >axis2c.prefix + +TESTS = axiom-test echo-test server-test + +endif diff --git a/sca-cpp/branches/cpp-contrib/components/webservice/axiom-test.cpp b/sca-cpp/branches/cpp-contrib/components/webservice/axiom-test.cpp new file mode 100644 index 0000000000..a3ab8e7e8f --- /dev/null +++ b/sca-cpp/branches/cpp-contrib/components/webservice/axiom-test.cpp @@ -0,0 +1,85 @@ +/* + * 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. + */ + +/* $Rev$ $Date$ */ + +/** + * Test Web service Axiom support functions. + */ + +#include <assert.h> +#include "stream.hpp" +#include "string.hpp" +#include "list.hpp" +#include "element.hpp" +#include "monad.hpp" +#include "value.hpp" +#include "perf.hpp" +#include "axis2.hpp" + +namespace tuscany { +namespace webservice { + +const string customerElement = +"<customer>" +"<name>jdoe</name>" +"<address><city>san francisco</city><state>ca</state></address>" +"<account><id>1234</id><balance>1000</balance></account>" +"<account><id>6789</id><balance>2000</balance></account>" +"<account><id>4567</id><balance>3000</balance></account>" +"</customer>"; + +bool testAxiom() { + const Axis2Context ax; + { + const failable<axiom_node_t*> n = stringToAxiomNode(customerElement, ax); + assert(hasContent(n)); + const failable<const string> c = axiomNodeToString(content(n), ax); + assert(hasContent(c)); + assert(content(c) == customerElement); + } + { + const list<value> arg = mklist<value>( + list<value>() + "ns1:echoString" + + (list<value>() + "@xmlns:ns1" + string("http://ws.apache.org/axis2/services/echo")) + + (list<value>() + "text" + string("Hello World!"))); + const failable<axiom_node_t*> n = valuesToAxiomNode(arg, ax); + assert(hasContent(n)); + const failable<const string> x = axiomNodeToString(content(n), ax); + assert(hasContent(x)); + assert(content(x) == "<ns1:echoString xmlns:ns1=\"http://ws.apache.org/axis2/services/echo\"><text>Hello World!</text></ns1:echoString>"); + const failable<const list<value> > l = axiomNodeToValues(content(n), ax); + assert(hasContent(l)); + assert(l == arg); + } + return true; +} + +} +} + +int main() { + tuscany::cout << "Testing..." << tuscany::endl; + + tuscany::webservice::testAxiom(); + + tuscany::cout << "OK" << tuscany::endl; + + return 0; +} diff --git a/sca-cpp/branches/cpp-contrib/components/webservice/axis2-conf b/sca-cpp/branches/cpp-contrib/components/webservice/axis2-conf new file mode 100755 index 0000000000..2e1f6116cd --- /dev/null +++ b/sca-cpp/branches/cpp-contrib/components/webservice/axis2-conf @@ -0,0 +1,53 @@ +#!/bin/sh + +# 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. + +# Generate an Axis2 server conf +here=`readlink -f $0`; here=`dirname $here` +root=`readlink -f $1` +axis2_prefix=`cat axis2c.prefix` + +# Create an Axis2 home directory +mkdir -p $root/axis2c +ln -f -s $axis2_prefix/lib $root/axis2c/lib +mkdir -p $root/axis2c/logs +mkdir -p $root/axis2c/modules +ln -f -s $axis2_prefix/modules/addressing $root/axis2c/modules/addressing +ln -f -s $axis2_prefix/modules/logging $root/axis2c/modules/logging +mkdir -p $root/axis2c/services + +# Install Tuscany Axis2 module and service +mkdir -p $root/axis2c/modules/tuscany +ln -f -s $here/.libs/libaxis2-dispatcher.so $root/axis2c/modules/tuscany/libaxis2-dispatcher.so +ln -f -s $here/module.xml $root/axis2c/modules/tuscany/module.xml +mkdir -p $root/axis2c/services/tuscany +ln -f -s $here/.libs/libaxis2-service.so $root/axis2c/services/tuscany/libaxis2-service.so +ln -f -s $here/services.xml $root/axis2c/services/tuscany/services.xml +cp $here/axis2.xml $root/axis2c/axis2.xml + +# Configure HTTPD Axis2 module +cat >>$root/conf/httpd.conf <<EOF +SetEnv AXIS2C_HOME $root/axis2c +LoadModule axis2_module $root/axis2c/lib/libmod_axis2.so +Axis2RepoPath $root/axis2c +Axis2LogFile $root/axis2c/logs/mod_axis2.log +Axis2LogLevel debug +<Location /axis2> + SetHandler axis2_module +</Location> +EOF diff --git a/sca-cpp/branches/cpp-contrib/components/webservice/axis2-dispatcher.cpp b/sca-cpp/branches/cpp-contrib/components/webservice/axis2-dispatcher.cpp new file mode 100644 index 0000000000..3f753e0e35 --- /dev/null +++ b/sca-cpp/branches/cpp-contrib/components/webservice/axis2-dispatcher.cpp @@ -0,0 +1,138 @@ +/* + * 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. + */ + +/* $Rev$ $Date$ */ + +/** + * Axis2/C module that dispatches all server requests to the Tuscany Axis/2C service. + */ + +#include "axis2.hpp" + +namespace tuscany { +namespace webservice { + +/** + * Determine the service and operation to dispatch a request to. + */ +axis2_svc_t* AXIS2_CALL dispatchFindService(axis2_msg_ctx_t* msg_ctx, const axutil_env_t* env) { + const axis2_conf_ctx_t* conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env); + const axis2_conf_t* conf = axis2_conf_ctx_get_conf(conf_ctx, env); + axis2_svc_t* svc = axis2_conf_get_svc(conf, env, "TuscanyService"); + return svc; +} + +axis2_op_t *AXIS2_CALL dispatchFindOp(unused axis2_msg_ctx_t* msg_ctx, const axutil_env_t* env, axis2_svc_t* svc) { + axutil_qname_t* op_qname = axutil_qname_create(env, "execute", NULL, NULL); + axis2_op_t *op = axis2_svc_get_op_with_name(svc, env, axutil_qname_get_localpart(op_qname, env)); + axutil_qname_free(op_qname, env); + return op; +} + +/** + * Dispatcher invoke function, called by Axis2/C. + */ +axis2_status_t AXIS2_CALL dispatchInvoke( struct axis2_handler* handler, const axutil_env_t* env, axis2_msg_ctx_t* msg_ctx) { + if (!(axis2_msg_ctx_get_server_side(msg_ctx, env))) + return AXIS2_SUCCESS; + axis2_msg_ctx_set_find_svc(msg_ctx, env, dispatchFindService); + axis2_msg_ctx_set_find_op(msg_ctx, env, dispatchFindOp); + return axis2_disp_find_svc_and_op(handler, env, msg_ctx); +} + +/** + * Create a dispatch handler. + */ +AXIS2_EXPORT axis2_handler_t* AXIS2_CALL dispatchHandler(const axutil_env_t* env, unused axutil_string_t* name) { + axis2_handler_t *handler = axis2_handler_create(env); + if (handler == NULL) + return NULL; + axis2_handler_set_invoke(handler, env, dispatchInvoke); + return handler; +} + +/** + * Initialize dispatch module. + */ +axis2_status_t AXIS2_CALL dispatchInit(unused axis2_module_t * module, unused const axutil_env_t * env, unused axis2_conf_ctx_t * conf_ctx, unused axis2_module_desc_t * module_desc) { + return AXIS2_SUCCESS; +} + +/** + * Initialize dispatch module function map. + */ +axis2_status_t AXIS2_CALL dispatchFuncMap(axis2_module_t * module, const axutil_env_t * env) { + module->handler_create_func_map = axutil_hash_make(env); + axutil_hash_set(module->handler_create_func_map, "TuscanyDispatcher", AXIS2_HASH_KEY_STRING, (const void *)dispatchHandler); + return AXIS2_SUCCESS; +} + +/** + * Shutdown dispatch module. + */ +axis2_status_t AXIS2_CALL dispatchShutdown(axis2_module_t* module, const axutil_env_t* env) { + if (module->handler_create_func_map != NULL) { + axutil_hash_free(module->handler_create_func_map, env); + module->handler_create_func_map = NULL; + } + AXIS2_FREE(env->allocator, module); + return AXIS2_SUCCESS; +} + +/** + * Return a new dispatch module. + */ +const axis2_module_ops_t dispatchOps = { + dispatchInit, + dispatchShutdown, + dispatchFuncMap +}; + +axis2_module_t * dispatchModule(const axutil_env_t* env) { + axis2_module_t *module = (axis2_module_t*)AXIS2_MALLOC(env->allocator, sizeof(axis2_module_t)); + if (module == NULL) + return NULL; + module->ops = &dispatchOps; + module->handler_create_func_map = NULL; + return module; +} + +} +} + +extern "C" +{ + +/** + * Axis2/C module entry point functions. + */ +AXIS2_EXPORT int axis2_get_instance(axis2_module_t** inst, const axutil_env_t* env) { + *inst = tuscany::webservice::dispatchModule(env); + if(*inst == NULL) + return AXIS2_FAILURE; + return AXIS2_SUCCESS; +} + +AXIS2_EXPORT int axis2_remove_instance(axis2_module_t* inst, const axutil_env_t* env) { + if (inst != NULL) + return tuscany::webservice::dispatchShutdown(inst, env); + return AXIS2_FAILURE; +} + +} diff --git a/sca-cpp/branches/cpp-contrib/components/webservice/axis2-service.cpp b/sca-cpp/branches/cpp-contrib/components/webservice/axis2-service.cpp new file mode 100644 index 0000000000..4c0ce22722 --- /dev/null +++ b/sca-cpp/branches/cpp-contrib/components/webservice/axis2-service.cpp @@ -0,0 +1,151 @@ +/* + * 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. + */ + +/* $Rev$ $Date$ */ + +/** + * Axis2/C service implementation that dispatches requests to SCA Web service components. + */ + +#include "value.hpp" +#include "string.hpp" +#include "../../modules/http/httpd.hpp" +#include "axis2.hpp" + +namespace tuscany { +namespace webservice { + +/** + * Initialize the service. + */ +int AXIS2_CALL serviceInit(unused axis2_svc_skeleton_t* svc_skeleton, unused const axutil_env_t* env) { + return AXIS2_SUCCESS; +} + +/** + * Free the service. + */ +int AXIS2_CALL serviceFree(axis2_svc_skeleton_t* svc_skeleton, const axutil_env_t* env) { + if (svc_skeleton) + AXIS2_FREE(env->allocator, svc_skeleton); + return AXIS2_SUCCESS; +} + +typedef struct axis2_apache2_out_transport_info { + axis2_http_out_transport_info_t out_transport_info; + request_rec *request; + axis2_char_t *encoding; +} axis2_apache2_out_transport_info_t; + +extern "C" { + extern module axis2_module; +} + +/** + * Service invoke function, called by Axis2/C. + */ +axiom_node_t *AXIS2_CALL serviceInvoke(unused axis2_svc_skeleton_t* svc_skeleton, const axutil_env_t* env, axiom_node_t* node, axis2_msg_ctx_t* msg_ctx) { + + // Check that we have an input node + if (node == NULL || axiom_node_get_node_type(node, env) != AXIOM_ELEMENT) + return NULL; + axiom_element_t *e = (axiom_element_t *) axiom_node_get_data_element(node, env); + if (e == NULL) + return NULL; + + // Get the function name + const char* func = axiom_element_get_localname(e, env); + if (func == NULL) + return NULL; + + // Get the target endpoint address + const axis2_endpoint_ref_t* epr = axis2_msg_ctx_get_from(msg_ctx, env); + if (epr == NULL) + return NULL; + string address = axis2_endpoint_ref_get_address(epr, env); + + // Get the underlying HTTPD request + axis2_out_transport_info_t* tinfo = axis2_msg_ctx_get_out_transport_info(msg_ctx, env); + axis2_apache2_out_transport_info_t* httpinfo = (axis2_apache2_out_transport_info_t*)tinfo; + request_rec* r = httpinfo->request; + httpdDebugRequest(r, "webservice::serviceInvoke"); + + // Parse the request Axiom node and construct request expression + Axis2Context ax(env); + const failable<const list<value> > lv = axiomNodeToValues(node, ax); + if (!hasContent(lv)) + return NULL; + const value expr = mklist<value>(func, content(lv)); + debug(expr, "webservice::serviceInvoke::expr"); + + // Retrieve the target lambda function from the HTTPD request and invoke it + const value* rv = const_cast<const value*>((value*)ap_get_module_config(r->request_config, &axis2_module)); + cout << "relay: " << rv << endl; + const lambda<value(const list<value>&)> relay = *rv; + const value res = relay(expr); + debug(res, "webservice::serviceInvoke::result"); + + // Construct response Axiom node + const failable<axiom_node_t*> rnode = valuesToAxiomNode(res, ax); + if (!hasContent(rnode)) + return NULL; + return content(rnode); +} + +/** + * Return a new service skeleton. + */ +const axis2_svc_skeleton_ops_t serviceOps = { + serviceInit, + serviceInvoke, + NULL, + serviceFree, + NULL +}; + +AXIS2_EXTERN axis2_svc_skeleton_t *AXIS2_CALL serviceSkeleton(const axutil_env_t* env) { + axis2_svc_skeleton_t* svc_skeleton = (axis2_svc_skeleton_t*)AXIS2_MALLOC(env->allocator, sizeof(axis2_svc_skeleton_t)); + svc_skeleton->ops = &serviceOps; + svc_skeleton->func_array = NULL; + return svc_skeleton; +} + +} +} + +extern "C" +{ + +/** + * Axis2/C service entry point functions. + */ +AXIS2_EXPORT int axis2_get_instance(struct axis2_svc_skeleton** inst, const axutil_env_t* env) { + *inst = tuscany::webservice::serviceSkeleton(env); + if (inst == NULL) + return AXIS2_FAILURE; + return AXIS2_SUCCESS; +} + +AXIS2_EXPORT int axis2_remove_instance(axis2_svc_skeleton_t* inst, const axutil_env_t* env) { + if (inst != NULL) + return AXIS2_SVC_SKELETON_FREE(inst, env); + return AXIS2_FAILURE; +} + +} diff --git a/sca-cpp/branches/cpp-contrib/components/webservice/axis2-test.cpp b/sca-cpp/branches/cpp-contrib/components/webservice/axis2-test.cpp new file mode 100644 index 0000000000..d7c2f3b671 --- /dev/null +++ b/sca-cpp/branches/cpp-contrib/components/webservice/axis2-test.cpp @@ -0,0 +1,71 @@ +/* + * 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. + */ + +/* $Rev$ $Date$ */ + +/** + * Test WebService Axis2 client support functions. + */ + +#include <assert.h> +#include "stream.hpp" +#include "string.hpp" +#include "list.hpp" +#include "element.hpp" +#include "monad.hpp" +#include "value.hpp" +#include "perf.hpp" +#include "axis2.hpp" + +namespace tuscany { +namespace webservice { + +bool testEval() { + const Axis2Context ax; + + const value func = "http://ws.apache.org/axis2/c/samples/echoString"; + const list<value> arg = mklist<value>( + list<value>() + "ns1:echoString" + + (list<value>() + "@xmlns:ns1" + string("http://ws.apache.org/axis2/services/echo")) + + (list<value>() + "text" + string("Hello World!"))); + + const failable<value> rval = evalExpr(mklist<value>(func, arg, string("http://localhost:9090/axis2/services/echo")), ax); + assert(hasContent(rval)); + + const list<value> r = mklist<value>( + list<value>() + "ns1:echoString" + + (list<value>() + "@xmlns:ns1" + string("http://ws.apache.org/axis2/c/samples")) + + (list<value>() + "text" + string("Hello World!"))); + assert(content(rval) == r); + + return true; +} + +} +} + +int main() { + tuscany::cout << "Testing..." << tuscany::endl; + + tuscany::webservice::testEval(); + + tuscany::cout << "OK" << tuscany::endl; + + return 0; +} diff --git a/sca-cpp/branches/cpp-contrib/components/webservice/axis2.hpp b/sca-cpp/branches/cpp-contrib/components/webservice/axis2.hpp new file mode 100644 index 0000000000..c2886edb71 --- /dev/null +++ b/sca-cpp/branches/cpp-contrib/components/webservice/axis2.hpp @@ -0,0 +1,194 @@ +/* + * 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. + */ + +/* $Rev$ $Date$ */ + +#ifndef tuscany_webservice_hpp +#define tuscany_webservice_hpp + +/** + * Web service invocation functions using Axis2. + */ +#include "config.hpp" + +// Ignore redundant declarations in Axiom headers +#ifdef WANT_MAINTAINER_MODE +#pragma GCC diagnostic ignored "-Wredundant-decls" +#endif +#include <axiom.h> +#include <axis2_client.h> +#include <axis2_module.h> +#include <axis2_addr_mod.h> +#include <axis2_conf_ctx.h> +#include <axis2_disp.h> +#include <axis2_http_out_transport_info.h> +#ifdef WANT_MAINTAINER_MODE +#pragma GCC diagnostic warning "-Wredundant-decls" +#endif + +#include "string.hpp" +#include "sstream.hpp" +#include "list.hpp" +#include "value.hpp" +#include "xml.hpp" +#include "monad.hpp" + +namespace tuscany { +namespace webservice { + +/** + * Represents an Axis2 runtime context. + */ +class Axis2Context { +public: + Axis2Context() : env(axutil_env_create_all("axis2.log", AXIS2_LOG_LEVEL_WARNING)), owner(true) { + } + + Axis2Context(const Axis2Context& ax) : env(ax.env), owner(false) { + } + + Axis2Context(const axutil_env_t* env) : env(const_cast<axutil_env_t*>(env)), owner(false) { + } + + ~Axis2Context() { + if (!owner || env == NULL) + return; + axutil_env_free(env); + } + +private: + axutil_env_t* env; + bool owner; + + friend const axutil_env_t* env(const Axis2Context& ax); +}; + +const axutil_env_t* env(const Axis2Context& ax) { + return ax.env; +} + +/** + * Return the latest Axis2 error in an Axis2 context. + */ +const string axis2Error(const Axis2Context& ax) { + ostringstream os; + os << env(ax)->error->error_number << " : " << AXIS2_ERROR_GET_MESSAGE(env(ax)->error); + return str(os); +} + +/** + * Convert a string to an Axiom node. + */ +const failable<axiom_node_t*> stringToAxiomNode(const string& s, const Axis2Context& ax) { + axiom_node_t* node = axiom_node_create_from_buffer(env(ax), const_cast<axis2_char_t*>(c_str(s))); + if (node == NULL) + return mkfailure<axiom_node_t*>(string("Couldn't convert XML to Axiom node: ") + axis2Error(ax)); + return node; +} + +/** + * Convert a list of values representing XML elements to an Axiom node. + */ +const failable<axiom_node_t*> valuesToAxiomNode(const list<value>& l, const Axis2Context& ax) { + const failable<list<string> > xml = writeXML(valuesToElements(l), false); + if (!hasContent(xml)) + return mkfailure<axiom_node_t*>(reason(xml)); + ostringstream os; + write(content(xml), os); + return stringToAxiomNode(str(os), ax); +} + +/** + * Convert an axiom node to a string. + */ +const failable<const string> axiomNodeToString(axiom_node_t* node, const Axis2Context& ax) { + const char* c = axiom_node_to_string(node, env(ax)); + if (c == NULL) + return mkfailure<const string>(string("Couldn't convert Axiom node to XML: ") + axis2Error(ax)); + const string s(c); + AXIS2_FREE(env(ax)->allocator, const_cast<char*>(c)); + return s; +} + +/** + * Convert an axiom node to a list of values representing XML elements. + */ +const failable<const list<value> > axiomNodeToValues(axiom_node_t* node, const Axis2Context& ax) { + const failable<const string> s = axiomNodeToString(node, ax); + if (!hasContent(s)) + return mkfailure<const list<value> >(reason(s)); + istringstream is(content(s)); + const failable<const list<value> > l = readXML(streamList(is)); + if (!hasContent(l)) + return l; + return elementsToValues(content(l)); +} + +/** + * Evaluate an expression in the form (soap-action-string, document, uri). Send the + * SOAP action and document to the Web Service at the given URI using Axis2. + */ +const failable<value> evalExpr(const value& expr, const Axis2Context& ax) { + debug(expr, "webservice::evalExpr::input"); + + // Extract func name and single argument + const value func(car<value>(expr)); + const list<value> param(cadr<value>(expr)); + const value uri(caddr<value>(expr)); + + // Create Axis2 client + axis2_svc_client_t *client = axis2_svc_client_create(env(ax), getenv("AXIS2C_HOME")); + if (client == NULL) + return mkfailure<value>("Couldn't create Axis2 client: " + axis2Error(ax)); + axis2_endpoint_ref_t *epr = axis2_endpoint_ref_create(env(ax), c_str(uri)); + axis2_options_t *opt = axis2_options_create(env(ax)); + axis2_options_set_to(opt, env(ax), epr); + axis2_options_set_action(opt, env(ax), (const axis2_char_t*)c_str(func)); + axis2_svc_client_set_options(client, env(ax), opt); + axis2_svc_client_engage_module(client, env(ax), AXIS2_MODULE_ADDRESSING); + + // Construct request Axiom node + const failable<axiom_node_t*> req = valuesToAxiomNode(param, ax); + if (!hasContent(req)) + return mkfailure<value>(reason(req)); + + // Call the Web service + axiom_node_t* res = axis2_svc_client_send_receive(client, env(ax), content(req)); + if (res == NULL) { + axis2_svc_client_free(client, env(ax)); + return mkfailure<value>("Couldn't invoke Axis2 service: " + axis2Error(ax)); + } + + // Parse result Axiom node + const failable<const list<value> > lval = axiomNodeToValues(res, ax); + if (!hasContent(lval)) + return mkfailure<value>(reason(lval)); + const value rval = content(lval); + debug(rval, "webservice::evalExpr::result"); + + // Cleanup + axis2_svc_client_free(client, env(ax)); + + return rval; +} + +} +} + +#endif /* tuscany_webservice_hpp */ diff --git a/sca-cpp/branches/cpp-contrib/components/webservice/axis2.xml b/sca-cpp/branches/cpp-contrib/components/webservice/axis2.xml new file mode 100644 index 0000000000..ea9b6d2194 --- /dev/null +++ b/sca-cpp/branches/cpp-contrib/components/webservice/axis2.xml @@ -0,0 +1,148 @@ +<!-- + 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. +--> +<axisconfig name="Axis2/C"> + <!-- ================================================= --> + <!-- Parameters --> + <!-- ================================================= --> + <!-- Uncomment following to enable MTOM support globally --> + <!--parameter name="enableMTOM" locked="false">true</parameter--> + + <!-- Set the suitable size for optimum memory usage when sending large attachments --> + <!--parameter name="MTOMBufferSize" locked="false">10</parameter--> + <!--parameter name="MTOMMaxBuffers" locked="false">1000</parameter--> + <!--parameter name="EnableMTOMServiceCallback" locked="false">true</parameter--> + <!--parameter name="attachmentDIR" locked="false">/path/to/the/attachment/caching/dir/</parameter--> + <!--parameter name="MTOMCachingCallback" locked="false">/path/to/the/caching_callback</parameter--> + <!--parameter name="MTOMSendingCallback" locked="false">/path/to/the/sending_callback</parameter--> + + <!-- Enable REST --> + <parameter name="enableREST" locked="false">true</parameter> + + <!-- Uncomment following to persist op_ctx, useful with RM --> + <!--parameter name="persistOperationContext" locked="false">true</parameter--> + + <!--if you want to extract the service archive file and work with that please uncomment this--> + <!--else , it wont extract archive file or does not take into consideration if someone drop--> + <!--exploded directory into /service directory--> + <!--<parameter name="extractServiceArchive" locked="false">true</parameter>--> + + + <!-- ================================================= --> + <!-- Message Receivers --> + <!-- ================================================= --> + <!-- This is the Deafult Message Receiver for the Request Response style Operations --> + <!--messageReceiver mep="INOUT" class="axis2_receivers"/--> + + + <!-- ================================================= --> + <!-- Transport Ins --> + <!-- ================================================= --> + + <transportReceiver name="http" class="axis2_http_receiver"> + <parameter name="port" locked="false">6060</parameter> + <parameter name="exposeHeaders" locked="true">false</parameter> + </transportReceiver> + + <!--transportReceiver name="https" class="axis2_http_receiver"> + <parameter name="port" locked="false">6060</parameter> + <parameter name="exposeHeaders" locked="true">false</parameter> + </transportReceiver--> + + <!--transportReceiver name="tcp" class="axis2_tcp_receiver"> + <parameter name="port" locked="false">6060</parameter> + </transportReceiver--> + + + <!-- ================================================= --> + <!-- Transport Outs --> + <!-- ================================================= --> + + <transportSender name="http" class="axis2_http_sender"> + <parameter name="PROTOCOL" locked="false">HTTP/1.1</parameter> + <parameter name="xml-declaration" insert="false"/> + <!--parameter name="Transfer-Encoding">chunked</parameter--> + <!--parameter name="HTTP-Authentication" username="" password="" locked="true"/--> + <!--parameter name="PROXY" proxy_host="127.0.0.1" proxy_port="8080" proxy_username="" proxy_password="" locked="true"/--> + </transportSender> + + <!-- Uncomment the following with appropriate parameters to enable the SSL transport sender. + Also make sure that the appropriate transport receiver is enabled above.--> + <!--transportSender name="https" class="axis2_http_sender"> + <parameter name="PROTOCOL" locked="false">HTTP/1.1</parameter> + <parameter name="xml-declaration" insert="false"/> + </transportSender> + <parameter name="SERVER_CERT">/path/to/ca/certificate</parameter> + <parameter name="KEY_FILE">/path/to/client/certificate/chain/file</parameter> + <parameter name="SSL_PASSPHRASE">passphrase</parameter> + --> + + <!-- Uncomment this one with the appropriate papameters to enable the TCP transport Sender--> + <!--transportSender name="tcp" class="axis2_tcp_sender"> + <parameter name="PROTOCOL" locked="false">TCP</parameter> + <parameter name="xml-declaration" insert="false"/> + </transportSender--> + + + <!-- ================================================= --> + <!-- Global Modules --> + <!-- ================================================= --> + <!-- Comment this to disable Addressing --> + <module ref="addressing"/> + + <!-- Tuscany dispatcher module --> + <module ref="tuscany"/> + + <!--Configuring module , providing paramters for modules whether they refer or not--> + <!--<moduleConfig name="addressing">--> + <!--<parameter name="addressingPara" locked="false">N/A</parameter>--> + <!--</moduleConfig>--> + + <!-- ================================================= --> + <!-- Phases --> + <!-- ================================================= --> + <phaseOrder type="inflow"> + <!-- System pre defined phases --> + <phase name="Transport"/> + <phase name="PreDispatch"/> + <phase name="Dispatch"/> + <phase name="PostDispatch"/> + <!--phase name="Security"/--> + <!-- End system pre defined phases --> + <!-- After PostDispatch phase, module or service author can add any phase as required --> + <!-- User defined phases could be added here --> + <!--phase name="userphase1"/--> + </phaseOrder> + <phaseOrder type="outflow"> + <!-- User defined phases could be added here --> + <!--phase name="userphase1"/--> + <!--system predefined phase--> + <phase name="MessageOut"/> + <!--phase name="Security"/--> + </phaseOrder> + <phaseOrder type="INfaultflow"> + <!-- User defined phases could be added here --> + <!--phase name="userphase1"/--> + </phaseOrder> + <phaseOrder type="Outfaultflow"> + <!-- User defined phases could be added here --> + <!--phase name="userphase1"/--> + <phase name="MessageOut"/> + </phaseOrder> +</axisconfig> + diff --git a/sca-cpp/branches/cpp-contrib/components/webservice/client-test.cpp b/sca-cpp/branches/cpp-contrib/components/webservice/client-test.cpp new file mode 100644 index 0000000000..9030a77676 --- /dev/null +++ b/sca-cpp/branches/cpp-contrib/components/webservice/client-test.cpp @@ -0,0 +1,94 @@ +/* + * 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. + */ + +/* $Rev$ $Date$ */ + +/** + * Test Web service component. + */ + +#include <assert.h> +#include "stream.hpp" +#include "string.hpp" +#include "list.hpp" +#include "element.hpp" +#include "value.hpp" +#include "monad.hpp" +#include "perf.hpp" +#include "../../modules/http/curl.hpp" +#include "axis2.hpp" + +namespace tuscany { +namespace webservice { + + +bool testModAxis2() { + const Axis2Context ax; + + const value func = "http://ws.apache.org/axis2/c/samples/echoString"; + const list<value> arg = mklist<value>( + list<value>() + "ns1:echoString" + + (list<value>() + "@xmlns:ns1" + string("http://ws.apache.org/axis2/services/echo")) + + (list<value>() + "text" + string("Hello World!"))); + + const failable<value> rval = evalExpr(mklist<value>(func, arg, string("http://localhost:8090/echo-listener")), ax); + assert(hasContent(rval)); + + const list<value> r = mklist<value>( + list<value>() + "ns1:echoString" + + (list<value>() + "@xmlns:ns1" + string("http://ws.apache.org/axis2/services/echo")) + + (list<value>() + "text" + string("Hello World!"))); + assert(content(rval) == r); + + return true; +} + +bool testEval() { + http::CURLSession cs; + + const value func = "http://ws.apache.org/axis2/c/samples/echoString"; + const list<value> arg = mklist<value>( + list<value>() + "ns1:echoString" + + (list<value>() + "@xmlns:ns1" + string("http://ws.apache.org/axis2/services/echo")) + + (list<value>() + "text" + string("Hello World!"))); + + const failable<value> rval = http::evalExpr(mklist<value>(func, arg), "http://localhost:8090/echo-client", cs); + assert(hasContent(rval)); + + const list<value> r = mklist<value>( + list<value>() + "ns1:echoString" + + (list<value>() + "@xmlns:ns1" + string("http://ws.apache.org/axis2/c/samples")) + + (list<value>() + "text" + string("Hello World!"))); + assert(content(rval) == r); + return true; +} + +} +} + +int main() { + tuscany::cout << "Testing..." << tuscany::endl; + + tuscany::webservice::testModAxis2(); + tuscany::webservice::testEval(); + + tuscany::cout << "OK" << tuscany::endl; + + return 0; +} diff --git a/sca-cpp/branches/cpp-contrib/components/webservice/echo-test b/sca-cpp/branches/cpp-contrib/components/webservice/echo-test new file mode 100755 index 0000000000..e5cd1d9a9d --- /dev/null +++ b/sca-cpp/branches/cpp-contrib/components/webservice/echo-test @@ -0,0 +1,37 @@ +#!/bin/sh + +# 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. + +# Setup +axis2_prefix=`cat axis2c.prefix` +export AXIS2C_HOME=$axis2_prefix +axis2="$axis2_prefix/bin/axis2_http_server" +pwd=`pwd` +cd "$axis2_prefix/bin" +$axis2 & +cd $pwd +sleep 1 + +# Test +./axis2-test 2>/dev/null +rc=$? + +# Cleanup +kill `ps -f | grep -v grep | grep "$axis2" | awk '{ print $2 }'` +sleep 1 +return $rc diff --git a/sca-cpp/branches/cpp-contrib/components/webservice/module.xml b/sca-cpp/branches/cpp-contrib/components/webservice/module.xml new file mode 100644 index 0000000000..8f6ba5018f --- /dev/null +++ b/sca-cpp/branches/cpp-contrib/components/webservice/module.xml @@ -0,0 +1,25 @@ +<!-- + 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. +--> +<module name="tuscany" class="axis2-dispatcher"> + <inflow> + <handler name="TuscanyDispatcher" class="axis2-dispatcher"> + <order phase="Dispatch"/> + </handler> + </inflow> +</module> diff --git a/sca-cpp/branches/cpp-contrib/components/webservice/server-test b/sca-cpp/branches/cpp-contrib/components/webservice/server-test new file mode 100755 index 0000000000..8311b94220 --- /dev/null +++ b/sca-cpp/branches/cpp-contrib/components/webservice/server-test @@ -0,0 +1,49 @@ +#!/bin/sh + +# 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. + +# Setup +../../modules/http/httpd-conf tmp 8090 ../../modules/http/htdocs +../../modules/server/server-conf tmp +../../modules/server/scheme-conf tmp +./axis2-conf tmp +cat >>tmp/conf/httpd.conf <<EOF +SCAContribution `pwd`/ +SCAComposite webservice.composite +EOF + +../../modules/http/httpd-start tmp + +axis2_prefix=`cat axis2c.prefix` +export AXIS2C_HOME=$axis2_prefix +axis2="$axis2_prefix/bin/axis2_http_server" +pwd=`pwd` +cd "$axis2_prefix/bin" +$axis2 & +cd $pwd +sleep 2 + +# Test +./client-test 2>/dev/null +rc=$? + +# Cleanup +kill `ps -f | grep -v grep | grep "${axis2}" | awk '{ print $2 }'` +../../modules/http/httpd-stop tmp +sleep 2 +return $rc diff --git a/sca-cpp/branches/cpp-contrib/components/webservice/server-test.scm b/sca-cpp/branches/cpp-contrib/components/webservice/server-test.scm new file mode 100644 index 0000000000..44e4eee92a --- /dev/null +++ b/sca-cpp/branches/cpp-contrib/components/webservice/server-test.scm @@ -0,0 +1,21 @@ +; 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. + +; Web service test case + +(define (echoString x) x) + diff --git a/sca-cpp/branches/cpp-contrib/components/webservice/services.xml b/sca-cpp/branches/cpp-contrib/components/webservice/services.xml new file mode 100644 index 0000000000..0adf136f4f --- /dev/null +++ b/sca-cpp/branches/cpp-contrib/components/webservice/services.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!-- + 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. +--> +<serviceGroup> +<service name="TuscanyService"> + <parameter name="ServiceClass" locked="xsd:false">axis2-service</parameter> + <operation name="execute"/> +</service> +</serviceGroup> diff --git a/sca-cpp/branches/cpp-contrib/components/webservice/webservice-client.cpp b/sca-cpp/branches/cpp-contrib/components/webservice/webservice-client.cpp new file mode 100644 index 0000000000..06db6c01b8 --- /dev/null +++ b/sca-cpp/branches/cpp-contrib/components/webservice/webservice-client.cpp @@ -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. + */ + +/* $Rev$ $Date$ */ + +/** + * Web service client component implementation. + */ + +#include "string.hpp" +#include "function.hpp" +#include "list.hpp" +#include "value.hpp" +#include "monad.hpp" +#include "axis2.hpp" + +namespace tuscany { +namespace webservice { + +/** + * Apply a function provided by a remote Web service using Axis2. + */ +const failable<value> apply(const value& func, const list<value>& params) { + const Axis2Context ax; + + // Extract parameters + const value doc = car<value>(params); + const lambda<value(const list<value>&)> l = cadr<value>(params); + + // Call the URI property lambda function to get the configured URI + const value uri = l(list<value>()); + + // Evaluate using Axis2 + return evalExpr(mklist<value>(func, doc, uri), ax); +} + +} +} + +extern "C" { + +const tuscany::value apply(const tuscany::list<tuscany::value>& params) { + const tuscany::value func(car(params)); + if (func == "start") + return tuscany::mkfailure<tuscany::value>(); + return tuscany::webservice::apply(func, cdr(params)); +} + +} diff --git a/sca-cpp/branches/cpp-contrib/components/webservice/webservice-listener.cpp b/sca-cpp/branches/cpp-contrib/components/webservice/webservice-listener.cpp new file mode 100644 index 0000000000..2127ecf0df --- /dev/null +++ b/sca-cpp/branches/cpp-contrib/components/webservice/webservice-listener.cpp @@ -0,0 +1,86 @@ +/* + * 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. + */ + +/* $Rev$ $Date$ */ + +/** + * Web service listener component implementation. + */ + +#include "string.hpp" +#include "function.hpp" +#include "list.hpp" +#include "value.hpp" +#include "monad.hpp" +#include "../../modules/http/httpd.hpp" +#include "axis2.hpp" + +namespace tuscany { +namespace webservice { + +/** + * Redirect an HTTP request to the Axis2/C HTTPD module. The given relay lambda function + * is stored in the HTTPD request, for later retrieval by the Axis2 service to relay the request + * to a target component. + */ +extern "C" { + extern module axis2_module; +} + +const value redirectToAxis2(const string& uri, request_rec* r, const value& relay) { + const failable<request_rec*, int> nr = httpd::internalRedirectRequest(uri, r); + if (!hasContent(nr)) + return value(reason(nr)); + ap_set_module_config(content(nr)->request_config, &axis2_module, const_cast<void*>((const void*)&relay)); + return value(httpd::internalRedirect(content(nr))); +} + +/** + * Handle an HTTP request. + */ +const failable<value> handle(const list<value>& params) { + + // Extract HTTPD request from the params + request_rec* r = httpd::request(car(params)); + httpdDebugRequest(r, "webservice::handle"); + + // Extract the relay lambda from the params and store it in the HTTPD request, + // for later retrieval by our Axis2 service + const value relay = cadr(params); + cout << "relay: " << &relay << endl; + + // Redirect HTTPD request to Mod-axis2 + if (r->args == NULL) + return redirectToAxis2(httpd::redirectURI("/axis2", string(r->uri)), r, relay); + return redirectToAxis2(httpd::redirectURI("/axis2", string(r->uri), string(r->args)), r, relay); +} + +} +} + +extern "C" { + +const tuscany::value apply(const tuscany::list<tuscany::value>& params) { + const tuscany::value func(car(params)); + if (func == "handle") + return tuscany::webservice::handle(cdr(params)); + return tuscany::mkfailure<tuscany::value>(); +} + +} diff --git a/sca-cpp/branches/cpp-contrib/components/webservice/webservice.composite b/sca-cpp/branches/cpp-contrib/components/webservice/webservice.composite new file mode 100644 index 0000000000..6d4055aad3 --- /dev/null +++ b/sca-cpp/branches/cpp-contrib/components/webservice/webservice.composite @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. +--> +<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" + xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1" + targetNamespace="http://tuscany.apache.org/xmlns/sca/components" + name="webservice-client"> + + <component name="webservice-client"> + <implementation.cpp path=".libs" library="libwebservice-client"/> + <property name="uri">http://localhost:9090/axis2/services/echo</property> + <service name="webservice-client"> + <t:binding.jsonrpc uri="echo-client"/> + </service> + </component> + + <component name="webservice-listener"> + <implementation.cpp path=".libs" library="libwebservice-listener"/> + <service name="webservice-listener"> + <t:binding.http uri="echo-listener"/> + </service> + <reference name="relay" target="echo"/> + </component> + + <component name="echo"> + <t:implementation.scheme script="server-test.scm"/> + <service name="echo"> + <t:binding.jsonrpc uri="echo"/> + </service> + </component> + +</composite> |