diff options
author | jsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68> | 2010-02-07 00:36:25 +0000 |
---|---|---|
committer | jsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68> | 2010-02-07 00:36:25 +0000 |
commit | bb4b895471e3165c71bdfd1fdae5e1ffde8f1696 (patch) | |
tree | 57bec175bb5dbf43303f7334162b9b2b4bda03c6 | |
parent | 00f9947613624b251551ba709824f97f1b6c2fb1 (diff) |
Moved server configuration to HTTPD postConfig phase, to avoid running configuration commands twice and added a way for runtime modules and components to handle start/restart/stop events. Improved build scripts a little, to not depend on external environment variables.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@907352 13f79535-47bb-0310-9956-ffa450edef68
64 files changed, 677 insertions, 235 deletions
diff --git a/sca-cpp/trunk/components/cache/mcache.cpp b/sca-cpp/trunk/components/cache/mcache.cpp index 46f707ee19..b1dc750ccb 100644 --- a/sca-cpp/trunk/components/cache/mcache.cpp +++ b/sca-cpp/trunk/components/cache/mcache.cpp @@ -99,7 +99,7 @@ const tuscany::value apply(const tuscany::list<tuscany::value>& params) { return tuscany::cache::put(cdr(params)); if (func == "delete") return tuscany::cache::del(cdr(params)); - return tuscany::mkfailure<tuscany::value>(tuscany::string("Function not supported: ") + func); + return tuscany::mkfailure<tuscany::value>(); } } diff --git a/sca-cpp/trunk/components/cache/server-test b/sca-cpp/trunk/components/cache/server-test index a30d14b1b6..821724295d 100755 --- a/sca-cpp/trunk/components/cache/server-test +++ b/sca-cpp/trunk/components/cache/server-test @@ -22,14 +22,11 @@ ../../modules/server/server-conf tmp ../../modules/server/scheme-conf tmp cat >>tmp/conf/httpd.conf <<EOF - -<Location /> SCAContribution `pwd`/ SCAComposite mcache.composite -</Location> EOF -apachectl -k start -d `pwd`/tmp +../../modules/http/httpd-start tmp mc="memcached -l 127.0.0.1 -m 4 -p 11211" $mc & @@ -41,6 +38,6 @@ rc=$? # Cleanup kill `ps -f | grep -v grep | grep "$mc" | awk '{ print $2 }'` -apachectl -k stop -d `pwd`/tmp +../../modules/http/httpd-stop tmp sleep 2 return $rc diff --git a/sca-cpp/trunk/components/chat/chat-listener.cpp b/sca-cpp/trunk/components/chat/chat-listener.cpp index 57642036a6..884965839a 100644 --- a/sca-cpp/trunk/components/chat/chat-listener.cpp +++ b/sca-cpp/trunk/components/chat/chat-listener.cpp @@ -36,7 +36,7 @@ namespace chat { /** * Initialize the component. */ -const failable<value> init(unused const list<value>& params) { +const failable<value> start(unused const list<value>& params) { //TODO establish a session with an XMPP server for a JID and mark the current server instance busy return value(true); @@ -49,9 +49,9 @@ extern "C" { const tuscany::value apply(const tuscany::list<tuscany::value>& params) { const tuscany::value func(car(params)); - if (func == "init") - return tuscany::chat::init(cdr(params)); - return tuscany::mkfailure<tuscany::value>(tuscany::string("Function not supported: ") + func); + if (func == "start") + return tuscany::chat::start(cdr(params)); + return tuscany::mkfailure<tuscany::value>(); } } diff --git a/sca-cpp/trunk/components/chat/chat-sender.cpp b/sca-cpp/trunk/components/chat/chat-sender.cpp index dfcae6796a..bd67bf7315 100644 --- a/sca-cpp/trunk/components/chat/chat-sender.cpp +++ b/sca-cpp/trunk/components/chat/chat-sender.cpp @@ -52,7 +52,7 @@ const tuscany::value apply(const tuscany::list<tuscany::value>& params) { const tuscany::value func(car(params)); if (func == "post") return tuscany::chat::post(cdr(params)); - return tuscany::mkfailure<tuscany::value>(tuscany::string("Function not supported: ") + func); + return tuscany::mkfailure<tuscany::value>(); } } diff --git a/sca-cpp/trunk/components/queue/Makefile.am b/sca-cpp/trunk/components/queue/Makefile.am index cee3ce7820..6bbdc119b4 100644 --- a/sca-cpp/trunk/components/queue/Makefile.am +++ b/sca-cpp/trunk/components/queue/Makefile.am @@ -17,10 +17,13 @@ if WANT_QUEUE +noinst_PROGRAMS = qpid-test client-test + INCLUDES = -I${QPIDC_INCLUDE} compdir=$(prefix)/components/queue comp_LTLIBRARIES = libqueue-sender.la libqueue-listener.la +comp_DATA = qpidc.prefix libqueue_sender_la_SOURCES = queue-sender.cpp libqueue_sender_la_LDFLAGS = -L${QPIDC_LIB} -R${QPIDC_LIB} -lqpidclient @@ -28,4 +31,15 @@ libqueue_sender_la_LDFLAGS = -L${QPIDC_LIB} -R${QPIDC_LIB} -lqpidclient libqueue_listener_la_SOURCES = queue-listener.cpp libqueue_listener_la_LDFLAGS = -L${QPIDC_LIB} -R${QPIDC_LIB} -lqpidclient +qpid_test_SOURCES = qpid-test.cpp +qpid_test_LDFLAGS = -L${QPIDC_LIB} -R${QPIDC_LIB} -lqpidclient + +client_test_SOURCES = client-test.cpp +client_test_LDFLAGS = -lxml2 -lcurl -lmozjs + +qpidc.prefix: $(top_builddir)/config.status + echo ${QPIDC_PREFIX} >qpidc.prefix + +#TESTS = qpid-test server-test + endif diff --git a/sca-cpp/trunk/components/queue/client-test.cpp b/sca-cpp/trunk/components/queue/client-test.cpp new file mode 100644 index 0000000000..121a739e0d --- /dev/null +++ b/sca-cpp/trunk/components/queue/client-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 queue 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" + +namespace tuscany { +namespace queue { + + +bool testPost() { + 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::queue::testPost(); + + tuscany::cout << "OK" << tuscany::endl; + + return 0; +} diff --git a/sca-cpp/trunk/components/queue/qpid-test.cpp b/sca-cpp/trunk/components/queue/qpid-test.cpp new file mode 100644 index 0000000000..97d8d2f5d5 --- /dev/null +++ b/sca-cpp/trunk/components/queue/qpid-test.cpp @@ -0,0 +1,64 @@ +/* + * 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 Qpid 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 "qpid.hpp" + +namespace tuscany { +namespace queue { + +bool testPost() { + QpidConnection qc; + + QpidSession qs(qc); + + // Post the item + const list<value> params; + const value key = ((lambda<value(list<value>)>)cadr(params))(list<value>()); + post(key, car(params), qs); + + return value(true); + return true; +} + +} +} + +int main() { + tuscany::cout << "Testing..." << tuscany::endl; + + tuscany::queue::testPost(); + + tuscany::cout << "OK" << tuscany::endl; + + return 0; +} diff --git a/sca-cpp/trunk/components/queue/queue-listener.cpp b/sca-cpp/trunk/components/queue/queue-listener.cpp index 6f1c54873c..75c53e7b41 100644 --- a/sca-cpp/trunk/components/queue/queue-listener.cpp +++ b/sca-cpp/trunk/components/queue/queue-listener.cpp @@ -44,7 +44,7 @@ QpidConnection qc; /** * Initialize the component. */ -const failable<value> init(const list<value>& params) { +const failable<value> start(const list<value>& params) { QpidSession qs(qc); // Declare the configured AMQP key / queue pair @@ -64,9 +64,9 @@ extern "C" { const tuscany::value apply(const tuscany::list<tuscany::value>& params) { const tuscany::value func(car(params)); - if (func == "init") - return tuscany::queue::init(cdr(params)); - return tuscany::mkfailure<tuscany::value>(tuscany::string("Function not supported: ") + func); + if (func == "start") + return tuscany::queue::start(cdr(params)); + return tuscany::mkfailure<tuscany::value>(); } } diff --git a/sca-cpp/trunk/components/queue/queue-sender.cpp b/sca-cpp/trunk/components/queue/queue-sender.cpp index fbbbd0376b..15128411c2 100644 --- a/sca-cpp/trunk/components/queue/queue-sender.cpp +++ b/sca-cpp/trunk/components/queue/queue-sender.cpp @@ -63,7 +63,7 @@ const tuscany::value apply(const tuscany::list<tuscany::value>& params) { const tuscany::value func(car(params)); if (func == "post") return tuscany::queue::post(cdr(params)); - return tuscany::mkfailure<tuscany::value>(tuscany::string("Function not supported: ") + func); + return tuscany::mkfailure<tuscany::value>(); } } diff --git a/sca-cpp/trunk/components/webservice/Makefile.am b/sca-cpp/trunk/components/webservice/Makefile.am index b12518076b..264b150c93 100644 --- a/sca-cpp/trunk/components/webservice/Makefile.am +++ b/sca-cpp/trunk/components/webservice/Makefile.am @@ -23,6 +23,7 @@ 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 @@ -45,6 +46,9 @@ 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/trunk/components/webservice/axis2-conf b/sca-cpp/trunk/components/webservice/axis2-conf index 28f8a0be94..2e1f6116cd 100755 --- a/sca-cpp/trunk/components/webservice/axis2-conf +++ b/sca-cpp/trunk/components/webservice/axis2-conf @@ -20,14 +20,15 @@ # 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 $AXIS2C_HOME/lib $root/axis2c/lib +ln -f -s $axis2_prefix/lib $root/axis2c/lib mkdir -p $root/axis2c/logs mkdir -p $root/axis2c/modules -ln -f -s $AXIS2C_HOME/modules/addressing $root/axis2c/modules/addressing -ln -f -s $AXIS2C_HOME/modules/logging $root/axis2c/modules/logging +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 @@ -41,6 +42,7 @@ 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 diff --git a/sca-cpp/trunk/components/webservice/axis2.hpp b/sca-cpp/trunk/components/webservice/axis2.hpp index 7a67702b5c..c2886edb71 100644 --- a/sca-cpp/trunk/components/webservice/axis2.hpp +++ b/sca-cpp/trunk/components/webservice/axis2.hpp @@ -57,7 +57,7 @@ namespace webservice { */ class Axis2Context { public: - Axis2Context() : env(axutil_env_create_all("tuscany.log", AXIS2_LOG_LEVEL_WARNING)), owner(true) { + Axis2Context() : env(axutil_env_create_all("axis2.log", AXIS2_LOG_LEVEL_WARNING)), owner(true) { } Axis2Context(const Axis2Context& ax) : env(ax.env), owner(false) { @@ -144,8 +144,6 @@ const failable<const list<value> > axiomNodeToValues(axiom_node_t* node, const A * 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 char* axis2Home = getenv("AXIS2C_HOME"); - const failable<value> evalExpr(const value& expr, const Axis2Context& ax) { debug(expr, "webservice::evalExpr::input"); @@ -155,16 +153,13 @@ const failable<value> evalExpr(const value& expr, const Axis2Context& ax) { 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_t *client = axis2_svc_client_create(env(ax), axis2Home); - if (client == NULL) { - axis2_endpoint_ref_free(epr, env(ax)); - axis2_options_free(opt, env(ax)); - return mkfailure<value>("Couldn't create Axis2 client: " + axis2Error(ax)); - } axis2_svc_client_set_options(client, env(ax), opt); axis2_svc_client_engage_module(client, env(ax), AXIS2_MODULE_ADDRESSING); diff --git a/sca-cpp/trunk/components/webservice/echo-test b/sca-cpp/trunk/components/webservice/echo-test index b999b1aede..5e7a380521 100755 --- a/sca-cpp/trunk/components/webservice/echo-test +++ b/sca-cpp/trunk/components/webservice/echo-test @@ -18,9 +18,11 @@ # under the License. # Setup -axis2="$AXIS2C_HOME/bin/axis2_http_server" +axis2_prefix=`cat axis2c.prefix` +export AXIS2C_HOME=$axis2_prefix +axis2="$axis2_prefix/bin/axis2_http_server" pwd=`pwd` -cd $AXIS2C_HOME/bin +cd "$axis2_prefix/bin" $axis2 & cd $pwd sleep 1 diff --git a/sca-cpp/trunk/components/webservice/server-test b/sca-cpp/trunk/components/webservice/server-test index eb3d53a33a..7d33223b3d 100755 --- a/sca-cpp/trunk/components/webservice/server-test +++ b/sca-cpp/trunk/components/webservice/server-test @@ -23,18 +23,17 @@ ../../modules/server/scheme-conf tmp ./axis2-conf tmp cat >>tmp/conf/httpd.conf <<EOF - -<Location /> SCAContribution `pwd`/ SCAComposite webservice.composite -</Location> EOF -apachectl -k start -d `pwd`/tmp +../../modules/http/httpd-start tmp -axis2="$AXIS2C_HOME/bin/axis2_http_server" +axis2_prefix=`cat axis2c.prefix` +export AXIS2C_HOME=$axis2_prefix +axis2="$axis2_prefix/bin/axis2_http_server" pwd=`pwd` -cd $AXIS2C_HOME/bin +cd "$axis2_prefix/bin" $axis2 & cd $pwd sleep 2 @@ -44,7 +43,7 @@ sleep 2 rc=$? # Cleanup -kill `ps -f | grep -v grep | grep "$axis2" | awk '{ print $2 }'` -apachectl -k stop -d `pwd`/tmp +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/trunk/components/webservice/webservice-client.cpp b/sca-cpp/trunk/components/webservice/webservice-client.cpp index cc3a15c734..ae4e472e65 100644 --- a/sca-cpp/trunk/components/webservice/webservice-client.cpp +++ b/sca-cpp/trunk/components/webservice/webservice-client.cpp @@ -56,7 +56,10 @@ const failable<value> apply(const value& func, const list<value>& params) { extern "C" { const tuscany::value apply(const tuscany::list<tuscany::value>& params) { - return tuscany::webservice::apply(car(params), cdr(params)); + const tuscany::value func(car(params)); + if (func == "start" || func == "stop" || func == "restart") + return tuscany::mkfailure<tuscany::value>(); + return tuscany::webservice::apply(func, cdr(params)); } } diff --git a/sca-cpp/trunk/components/webservice/webservice-listener.cpp b/sca-cpp/trunk/components/webservice/webservice-listener.cpp index 7198a00749..2127ecf0df 100644 --- a/sca-cpp/trunk/components/webservice/webservice-listener.cpp +++ b/sca-cpp/trunk/components/webservice/webservice-listener.cpp @@ -80,7 +80,7 @@ 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>(tuscany::string("Function not supported: ") + func); + return tuscany::mkfailure<tuscany::value>(); } } diff --git a/sca-cpp/trunk/configure.ac b/sca-cpp/trunk/configure.ac index 26864d80c2..1ac3a9e5bd 100644 --- a/sca-cpp/trunk/configure.ac +++ b/sca-cpp/trunk/configure.ac @@ -119,12 +119,15 @@ AC_SUBST(APR_LIB) AC_MSG_CHECKING([for httpd]) AC_ARG_WITH([httpd], [AC_HELP_STRING([--with-httpd=PATH], [path to installed Apache HTTPD [default=/usr/local/apache2]])], [ + HTTPD_PREFIX="${withval}" HTTPD_INCLUDE="${withval}/include" AC_MSG_RESULT("${withval}") ], [ + HTTPD_PREFIX="/usr/local/apache2" HTTPD_INCLUDE="/usr/local/apache2/include" AC_MSG_RESULT(/usr/local/apache2/lib) ]) +AC_SUBST(HTTPD_PREFIX) AC_SUBST(HTTPD_INCLUDE) # Configure TUSCANY_SCACPP path variable. @@ -310,14 +313,17 @@ fi # Configure path to Java includes and lib. AC_MSG_CHECKING([for java]) AC_ARG_WITH([java], [AC_HELP_STRING([--with-java=PATH], [path to installed Java [default=/usr/lib/jvm/default-java]])], [ + JAVA_PREFIX="${withval}" JAVA_INCLUDE="${withval}/include" JAVA_LIB="${withval}/jre/lib/i386" AC_MSG_RESULT("${withval}") ], [ + JAVA_PREFIX="/usr/lib/jvm/default-java" JAVA_INCLUDE="/usr/lib/jvm/default-java/include" JAVA_LIB="/usr/lib/jvm/default-java/jre/lib/i386" AC_MSG_RESULT(/usr/lib/jvm/default-java) ]) +AC_SUBST(JAVA_PREFIX) AC_SUBST(JAVA_INCLUDE) AC_SUBST(JAVA_LIB) @@ -348,14 +354,17 @@ fi # Configure path to Apache Axis2C includes and lib. AC_MSG_CHECKING([for axis2c]) AC_ARG_WITH([axis2c], [AC_HELP_STRING([--with-axis2c=PATH], [path to installed Apache Axis2C [default=/usr/local/axis2c]])], [ + AXIS2C_PREFIX="${withval}" AXIS2C_INCLUDE="${withval}/include/axis2-1.6.0" AXIS2C_LIB="${withval}/lib" AC_MSG_RESULT("${withval}") ], [ + AXIS2C_PREFIX="/usr/local/axis2c" AXIS2C_INCLUDE="/usr/local/axis2c/include/axis2-1.6.0" AXIS2C_LIB="/usr/local/axis2c/lib" AC_MSG_RESULT(/usr/local/axis2c) ]) +AC_SUBST(AXIS2C_PREFIX) AC_SUBST(AXIS2C_INCLUDE) AC_SUBST(AXIS2C_LIB) @@ -404,14 +413,17 @@ fi # Configure path to Apache Qpid/C++ includes and lib. AC_MSG_CHECKING([for qpidc]) AC_ARG_WITH([qpidc], [AC_HELP_STRING([--with-qpidc=PATH], [path to installed Apache Qpid/C++ [default=/usr/local]])], [ + QPIDC_PREFIX="${withval}" QPIDC_INCLUDE="${withval}/include" QPIDC_LIB="${withval}/lib" AC_MSG_RESULT("${withval}") ], [ + QPIDC_PREFIX="/usr/local" QPIDC_INCLUDE="/usr/local/include" QPIDC_LIB="/usr/local/lib" AC_MSG_RESULT(/usr/local) ]) +AC_SUBST(QPIDC_PREFIX) AC_SUBST(QPIDC_INCLUDE) AC_SUBST(QPIDC_LIB) @@ -466,7 +478,7 @@ AC_ARG_ENABLE(chat, [AS_HELP_STRING([--enable-chat], [enable Chat component [def [ AC_MSG_RESULT(no)]) if test "${want_chat}" = "true"; then LIBS="-L${LIBSTROPHE_LIB} ${default_LIBS}" - AC_CHECK_LIB([strophe], [xmpp_initialize], [], [AC_MSG_ERROR([couldn't find a suitable libstrophe, use --with-libstrophe=PATH])], [-lexpat -lssl -lresolv]) + #AC_CHECK_LIB([strophe], [xmpp_initialize], [], [AC_MSG_ERROR([couldn't find a suitable libstrophe, use --with-libstrophe=PATH])], [-lexpat -lssl -lresolv]) AM_CONDITIONAL([WANT_CHAT], true) AC_DEFINE([WANT_CHAT], 1, [enable Chat component]) else diff --git a/sca-cpp/trunk/etc/git-exclude b/sca-cpp/trunk/etc/git-exclude index e0e49eb902..29c58979a8 100644 --- a/sca-cpp/trunk/etc/git-exclude +++ b/sca-cpp/trunk/etc/git-exclude @@ -62,6 +62,7 @@ doxygen *.class *.stamp *.jar +*.prefix # Specific ignores kernel-test @@ -83,4 +84,5 @@ java-shell script-test axiom-test axis2-test +qpid-test diff --git a/sca-cpp/trunk/kernel/fstream.hpp b/sca-cpp/trunk/kernel/fstream.hpp index 81f6a39f64..45cf54df4a 100644 --- a/sca-cpp/trunk/kernel/fstream.hpp +++ b/sca-cpp/trunk/kernel/fstream.hpp @@ -146,9 +146,15 @@ template<typename V> const bool debug(const V& v, const string& msg) { return true; } +const bool debug(const string& msg) { + cerr << msg << endl; + return true; +} + #else #define debug(v, msg) +#define debug(msg) #endif diff --git a/sca-cpp/trunk/kernel/monad.hpp b/sca-cpp/trunk/kernel/monad.hpp index a312827f6e..8aa4bc1662 100644 --- a/sca-cpp/trunk/kernel/monad.hpp +++ b/sca-cpp/trunk/kernel/monad.hpp @@ -241,6 +241,7 @@ private: template<typename A, typename B> friend const A content(const failable<A, B>& m); template<typename A, typename B> friend const B reason(const failable<A, B>& m); template<typename A, typename B> friend const failable<A, B> mkfailure(const B& f); + template<typename A> friend const failable<A, string> mkfailure(); bool hasv; V v; @@ -282,6 +283,10 @@ template<typename V> const failable<V> mkfailure(const char* f) { return mkfailure<V, string>(string(f)); } +template<typename V> const failable<V> mkfailure() { + return failable<V, string>(false, string()); +} + template<typename V, typename F> const lambda<failable<V, F>(const V)> failure() { return mkfailure<V, F>; } diff --git a/sca-cpp/trunk/modules/http/Makefile.am b/sca-cpp/trunk/modules/http/Makefile.am index 0e1364747c..b522113423 100644 --- a/sca-cpp/trunk/modules/http/Makefile.am +++ b/sca-cpp/trunk/modules/http/Makefile.am @@ -19,7 +19,13 @@ noinst_PROGRAMS = curl-test INCLUDES = -I${HTTPD_INCLUDE} +httpdir=$(prefix)/modules/http +http_DATA = httpd.prefix + curl_test_SOURCES = curl-test.cpp curl_test_LDFLAGS = -lxml2 -lcurl -lmozjs +httpd.prefix: $(top_builddir)/config.status + echo ${HTTPD_PREFIX} >httpd.prefix + TESTS = httpd-test http-test diff --git a/sca-cpp/trunk/modules/http/http-test b/sca-cpp/trunk/modules/http/http-test index bf6230aec8..9f65b37eec 100755 --- a/sca-cpp/trunk/modules/http/http-test +++ b/sca-cpp/trunk/modules/http/http-test @@ -19,7 +19,7 @@ # Setup ./httpd-conf tmp 8090 htdocs -apachectl -k start -d `pwd`/tmp +./httpd-start tmp sleep 2 # Test @@ -27,6 +27,6 @@ sleep 2 rc=$? # Cleanup -apachectl -k stop -d `pwd`/tmp +./httpd-stop tmp sleep 2 return $rc diff --git a/sca-cpp/trunk/modules/http/httpd-conf b/sca-cpp/trunk/modules/http/httpd-conf index 686bfbcec7..434040803d 100755 --- a/sca-cpp/trunk/modules/http/httpd-conf +++ b/sca-cpp/trunk/modules/http/httpd-conf @@ -27,6 +27,7 @@ mkdir -p $root mkdir -p $root/logs mkdir -p $root/conf cat >$root/conf/httpd.conf <<EOF +ErrorLog $root/logs/error_log ServerName http://127.0.0.1:$port Listen $port DocumentRoot $htdocs diff --git a/sca-cpp/trunk/modules/http/httpd-restart b/sca-cpp/trunk/modules/http/httpd-restart new file mode 100755 index 0000000000..92f27eb0df --- /dev/null +++ b/sca-cpp/trunk/modules/http/httpd-restart @@ -0,0 +1,25 @@ +#!/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. + +# Restart httpd server +here=`readlink -f $0`; here=`dirname $here` +root=`readlink -f $1` + +httpd_prefix=`cat $here/httpd.prefix` +$httpd_prefix/bin/apachectl -k graceful -d $root diff --git a/sca-cpp/trunk/modules/http/httpd-start b/sca-cpp/trunk/modules/http/httpd-start new file mode 100755 index 0000000000..91fc5284af --- /dev/null +++ b/sca-cpp/trunk/modules/http/httpd-start @@ -0,0 +1,25 @@ +#!/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. + +# Start httpd server +here=`readlink -f $0`; here=`dirname $here` +root=`readlink -f $1` + +httpd_prefix=`cat $here/httpd.prefix` +$httpd_prefix/bin/apachectl -E $root/logs/error_log -k start -d $root diff --git a/sca-cpp/trunk/modules/http/httpd-stop b/sca-cpp/trunk/modules/http/httpd-stop new file mode 100755 index 0000000000..7f4fe94629 --- /dev/null +++ b/sca-cpp/trunk/modules/http/httpd-stop @@ -0,0 +1,25 @@ +#!/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. + +# Stop httpd server +here=`readlink -f $0`; here=`dirname $here` +root=`readlink -f $1` + +httpd_prefix=`cat $here/httpd.prefix` +$httpd_prefix/bin/apachectl -k graceful-stop -d $root diff --git a/sca-cpp/trunk/modules/http/httpd-test b/sca-cpp/trunk/modules/http/httpd-test index 762c4c7f6b..952a58937a 100755 --- a/sca-cpp/trunk/modules/http/httpd-test +++ b/sca-cpp/trunk/modules/http/httpd-test @@ -21,7 +21,7 @@ echo "Testing..." # Setup ./httpd-conf tmp 8090 htdocs -apachectl -k start -d `pwd`/tmp +./httpd-start tmp sleep 2 # Test HTTP GET @@ -30,7 +30,7 @@ diff tmp/index.html htdocs/index.html rc=$? # Cleanup -apachectl -k stop -d `pwd`/tmp +./httpd-stop tmp sleep 2 if [ "$rc" = "0" ]; then echo "OK" diff --git a/sca-cpp/trunk/modules/http/httpd.hpp b/sca-cpp/trunk/modules/http/httpd.hpp index 43e75bf769..6b08c3b838 100644 --- a/sca-cpp/trunk/modules/http/httpd.hpp +++ b/sca-cpp/trunk/modules/http/httpd.hpp @@ -42,7 +42,7 @@ #include "util_script.h" #include "util_md5.h" #include "http_config.h" - +#include "ap_mpm.h" #include "mod_core.h" #include "string.hpp" @@ -65,21 +65,14 @@ template<typename C> const C& serverConf(const request_rec* r, const module* mod return *(C*)ap_get_module_config(r->server->module_config, mod); } -template<typename C> C& serverConf(const cmd_parms *cmd, const module* mod) { - return *(C*)ap_get_module_config(cmd->server->module_config, mod); +template<typename C> C& serverConf(const server_rec* s, const module* mod) { + return *(C*)ap_get_module_config(s->module_config, mod); } - -/** - * Returns a directory-scoped module configuration. - */ -template<typename C> void *makeDirConf(apr_pool_t *p, char *dirspec) { - return new (gc_new<C>(p)) C(dirspec); +template<typename C> C& serverConf(const cmd_parms *cmd, const module* mod) { + return *(C*)ap_get_module_config(cmd->server->module_config, mod); } -template<typename C> C& dirConf(const request_rec* r, const module* mod) { - return *(C*)ap_get_module_config(r->per_dir_config, mod); -} /** * Convert a path string to a list of values. @@ -404,6 +397,23 @@ const int internalRedirect(const string& uri, request_rec* r) { return httpd::internalRedirect(content(nr)); } +/** + * Put a value in the process user data. + */ +const bool putUserData(const string& k, const int v, const server_rec* s) { + apr_pool_userdata_set((const void *)v, c_str(k), apr_pool_cleanup_null, s->process->pool); + return true; +} + +/** + * Return a user data value. + */ +const int userData(const string& k, const server_rec* s) { + void* v = (int)0; + apr_pool_userdata_get(&v, c_str(k), s->process->pool); + return (int)v; +} + } } diff --git a/sca-cpp/trunk/modules/java/Makefile.am b/sca-cpp/trunk/modules/java/Makefile.am index 5ef145c6e3..5402ab495e 100644 --- a/sca-cpp/trunk/modules/java/Makefile.am +++ b/sca-cpp/trunk/modules/java/Makefile.am @@ -15,9 +15,8 @@ # specific language governing permissions and limitations # under the License. -datadir=$(prefix)/modules/java JAVAROOT = $(top_builddir)/modules/java -libdir=$(prefix)/lib +libdir = $(prefix)/lib if WANT_JAVA @@ -50,6 +49,12 @@ CLEANFILES = ${jarfile} org/apache/tuscany/*.class test/*.class client_test_SOURCES = client-test.cpp client_test_LDFLAGS = -lxml2 -lcurl -lmozjs +prefixdir = $(top_builddir)/modules/java +prefix_DATA = java.prefix + +java.prefix: $(top_builddir)/config.status + echo ${JAVA_PREFIX} >java.prefix + TESTS = java-test server-test endif diff --git a/sca-cpp/trunk/modules/java/driver.hpp b/sca-cpp/trunk/modules/java/driver.hpp index 5f117b8e68..ddfc057940 100644 --- a/sca-cpp/trunk/modules/java/driver.hpp +++ b/sca-cpp/trunk/modules/java/driver.hpp @@ -48,6 +48,7 @@ const value evalDriverLoop(const JavaRuntime& jr, const JavaClass jc, istream& i const bool evalDriverRun(const char* name, istream& in, ostream& out) { scheme::setupDisplay(out); + JavaRuntime javaRuntime; const failable<JavaClass> jc = readClass(javaRuntime, ".", name); if (!hasContent(jc)) return true; diff --git a/sca-cpp/trunk/modules/java/eval.hpp b/sca-cpp/trunk/modules/java/eval.hpp index 4272543506..e10ec29a0b 100644 --- a/sca-cpp/trunk/modules/java/eval.hpp +++ b/sca-cpp/trunk/modules/java/eval.hpp @@ -161,7 +161,7 @@ public: jmethodID iterableCdr; jmethodID iterableIsNil; -} javaRuntime; +}; /** * Return the last exception that occurred in a JVM. @@ -210,6 +210,8 @@ public: } const value operator()(const list<value>& expr) const { + if (isNil(expr)) + return func(expr); const value& op(car(expr)); if (op == "equals") return value(cadr(expr) == this); @@ -495,8 +497,15 @@ const failable<value> evalClass(const JavaRuntime& jr, const value& expr, const // Lookup the Java function named as the expression operand const list<value> func = assoc<value>(car<value>(expr), jc.m); - if (isNil(func)) + if (isNil(func)) { + + // The start, stop, and restart functions are optional + const value fn = car<value>(expr); + if (fn == "start" || fn == "stop" || fn == "restart") + return value(false); + return mkfailure<value>(string("Couldn't find function: ") + car<value>(expr) + " : " + lastException(jr)); + } const jmethodID fid = (jmethodID)(long)(double)cadr(func); // Convert args to Java jvalues diff --git a/sca-cpp/trunk/modules/java/java-test.cpp b/sca-cpp/trunk/modules/java/java-test.cpp index d050180be8..f811a4f58d 100644 --- a/sca-cpp/trunk/modules/java/java-test.cpp +++ b/sca-cpp/trunk/modules/java/java-test.cpp @@ -33,6 +33,7 @@ namespace java { bool testEvalExpr() { gc_scoped_pool pool; + JavaRuntime javaRuntime; { const failable<JavaClass> obj = readClass(javaRuntime, ".", "test.CalcImpl"); assert(hasContent(obj)); @@ -77,6 +78,7 @@ const value add(const list<value>& args) { bool testEvalLambda() { gc_scoped_pool pool; + JavaRuntime javaRuntime; { const failable<JavaClass> obj = readClass(javaRuntime, ".", "test.CalcImpl"); assert(hasContent(obj)); @@ -98,6 +100,7 @@ bool testEvalLambda() { bool testClassLoader() { gc_scoped_pool pool; + JavaRuntime javaRuntime; const failable<JavaClass> obj = readClass(javaRuntime, ".", "org.apache.tuscany.ClassLoader$Test"); assert(hasContent(obj)); const value exp = mklist<value>("testClassLoader"); @@ -109,6 +112,7 @@ bool testClassLoader() { bool testIterableUtil() { gc_scoped_pool pool; + JavaRuntime javaRuntime; const failable<JavaClass> obj = readClass(javaRuntime, ".", "org.apache.tuscany.IterableUtil$Test"); assert(hasContent(obj)); const value exp = mklist<value>("testList"); diff --git a/sca-cpp/trunk/modules/java/mod-java.cpp b/sca-cpp/trunk/modules/java/mod-java.cpp index a5dc48679d..b8ac642c0e 100644 --- a/sca-cpp/trunk/modules/java/mod-java.cpp +++ b/sca-cpp/trunk/modules/java/mod-java.cpp @@ -37,15 +37,38 @@ namespace server { namespace modeval { /** + * Start the module. + */ +const failable<bool> start(unused ServerConf& sc) { + // Start a Java runtime + sc.moduleConf = new (gc_new<java::JavaRuntime>()) java::JavaRuntime(); + return true; +} + +/** + * Stop the module. + */ +const failable<bool> stop(unused ServerConf& sc) { + return true; +} + +/** + * Restart the module. + */ +const failable<bool> restart(unused ServerConf& sc) { + return true; +} + +/** * Evaluate a Java component implementation and convert it to an applicable * lambda function. */ -const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px) { +const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px, modeval::ServerConf& sc) { const string itype(elementName(impl)); if (contains(itype, ".java")) - return modjava::evalImplementation(path, impl, px); + return modjava::evalImplementation(path, impl, px, sc); if (contains(itype, ".cpp")) - return modcpp::evalImplementation(path, impl, px); + return modcpp::evalImplementation(path, impl, px, sc); return mkfailure<lambda<value(const list<value>&)> >(string("Unsupported implementation type: ") + itype); } diff --git a/sca-cpp/trunk/modules/java/mod-java.hpp b/sca-cpp/trunk/modules/java/mod-java.hpp index a2235fc17f..ccb6d9262b 100644 --- a/sca-cpp/trunk/modules/java/mod-java.hpp +++ b/sca-cpp/trunk/modules/java/mod-java.hpp @@ -34,24 +34,32 @@ #include "value.hpp" #include "monad.hpp" #include "eval.hpp" -#include "../http/httpd.hpp" +#include "../server/mod-eval.hpp" namespace tuscany { namespace server { namespace modjava { /** + * Return the Java runtime configured in a server. + */ +java::JavaRuntime& javaRuntime(modeval::ServerConf sc) { + return *(java::JavaRuntime*)sc.moduleConf; +} + +/** * Apply a Java component implementation function. */ struct applyImplementation { java::JavaClass impl; const list<value> px; - applyImplementation(const java::JavaClass& impl, const list<value>& px) : impl(impl), px(px) { + java::JavaRuntime& jr; + applyImplementation(const java::JavaClass& impl, const list<value>& px, java::JavaRuntime& jr) : impl(impl), px(px), jr(jr) { } const value operator()(const list<value>& params) const { const value expr = append<value>(params, px); debug(expr, "modeval::java::applyImplementation::input"); - const failable<value> val = java::evalClass(java::javaRuntime, expr, impl); + const failable<value> val = java::evalClass(jr, expr, impl); debug(val, "modeval::java::applyImplementation::result"); if (!hasContent(val)) return mklist<value>(value(), reason(val)); @@ -63,12 +71,12 @@ struct applyImplementation { * Evaluate a Java component implementation and convert it to an applicable * lambda function. */ -const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px) { +const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px, modeval::ServerConf& sc) { const string cn(attributeValue("class", impl)); - const failable<java::JavaClass> jc = java::readClass(java::javaRuntime, path, cn); + const failable<java::JavaClass> jc = java::readClass(javaRuntime(sc), path, cn); if (!hasContent(jc)) return mkfailure<lambda<value(const list<value>&)> >(reason(jc)); - return lambda<value(const list<value>&)>(applyImplementation(content(jc), px)); + return lambda<value(const list<value>&)>(applyImplementation(content(jc), px, javaRuntime(sc))); } } diff --git a/sca-cpp/trunk/modules/java/server-test b/sca-cpp/trunk/modules/java/server-test index 45c5efafb2..fbd12e5542 100755 --- a/sca-cpp/trunk/modules/java/server-test +++ b/sca-cpp/trunk/modules/java/server-test @@ -22,16 +22,13 @@ ../server/server-conf tmp ./java-conf tmp cat >>tmp/conf/httpd.conf <<EOF - -<Location /> SCAContribution `pwd`/ SCAComposite domain-test.composite -</Location> EOF export CLASSPATH="`pwd`/libmod-tuscany-java-1.0.jar:`pwd`" -apachectl -k start -d `pwd`/tmp +../http/httpd-start tmp sleep 2 # Test @@ -39,6 +36,6 @@ sleep 2 rc=$? # Cleanup -apachectl -k stop -d `pwd`/tmp +../http/httpd-stop tmp sleep 2 return $rc diff --git a/sca-cpp/trunk/modules/java/wiring-test b/sca-cpp/trunk/modules/java/wiring-test index 7b47787b28..c0b6cbfd62 100755 --- a/sca-cpp/trunk/modules/java/wiring-test +++ b/sca-cpp/trunk/modules/java/wiring-test @@ -24,16 +24,13 @@ echo "Testing..." ../server/server-conf tmp ./java-conf tmp cat >>tmp/conf/httpd.conf <<EOF - -<Location /> SCAContribution `pwd`/ SCAComposite domain-test.composite -</Location> EOF export CLASSPATH="`pwd`/libmod-tuscany-java-1.0.jar:`pwd`" -apachectl -k start -d `pwd`/tmp +../http/httpd-start tmp sleep 2 # Test HTTP GET @@ -73,7 +70,7 @@ if [ "$rc" = "0" ]; then fi # Cleanup -apachectl -k stop -d `pwd`/tmp +../http/httpd-stop tmp sleep 2 if [ "$rc" = "0" ]; then echo "OK" diff --git a/sca-cpp/trunk/modules/python/driver.hpp b/sca-cpp/trunk/modules/python/driver.hpp index a1467c41a8..2820201057 100644 --- a/sca-cpp/trunk/modules/python/driver.hpp +++ b/sca-cpp/trunk/modules/python/driver.hpp @@ -47,6 +47,7 @@ const value evalDriverLoop(PyObject* script, istream& in, ostream& out) { } const bool evalDriverRun(const char* path, istream& in, ostream& out) { + PythonRuntime py; scheme::setupDisplay(out); ifstream is(path); failable<PyObject*> script = readScript(path, is); diff --git a/sca-cpp/trunk/modules/python/eval.hpp b/sca-cpp/trunk/modules/python/eval.hpp index 1b9392aed7..09c2cba92d 100644 --- a/sca-cpp/trunk/modules/python/eval.hpp +++ b/sca-cpp/trunk/modules/python/eval.hpp @@ -39,16 +39,23 @@ namespace python { */ class PythonRuntime { public: - PythonRuntime() { - Py_Initialize(); - + PythonRuntime() : owner(true) { + Py_InitializeEx(0); setupIO(); } + PythonRuntime(unused const PythonRuntime& r) : owner(false) { + } + ~PythonRuntime() { + if (!owner) + return; + //Py_Finalize(); } -} pythonRuntime; +private: + const bool owner; +}; /** * Declare conversion functions. @@ -211,8 +218,15 @@ const failable<value> evalScript(const value& expr, PyObject* script) { // Get the requested function PyObject* func = PyObject_GetAttrString(script, c_str(car<value>(expr))); - if (func == NULL) + if (func == NULL) { + + // The start, stop, and restart functions are optional + const value fn = car<value>(expr); + if (fn == "start" || fn == "stop" || fn == "restart") + return value(false); + return mkfailure<value>(string("Couldn't find function: ") + car<value>(expr) + " : " + lastError()); + } if (!PyCallable_Check(func)) { Py_DECREF(func); return mkfailure<value>(string("Couldn't find callable function: ") + car<value>(expr)); diff --git a/sca-cpp/trunk/modules/python/mod-python.cpp b/sca-cpp/trunk/modules/python/mod-python.cpp index 1c35467b4b..a45b83997f 100644 --- a/sca-cpp/trunk/modules/python/mod-python.cpp +++ b/sca-cpp/trunk/modules/python/mod-python.cpp @@ -37,15 +37,38 @@ namespace server { namespace modeval { /** + * Start the module. + */ +const failable<bool> start(unused ServerConf& sc) { + // Start a Python runtime + sc.moduleConf = new (gc_new<python::PythonRuntime>()) python::PythonRuntime(); + return true; +} + +/** + * Stop the module. + */ +const failable<bool> stop(unused ServerConf& sc) { + return true; +} + +/** + * Restart the module. + */ +const failable<bool> restart(unused ServerConf& sc) { + return true; +} + +/** * Evaluate a Python component implementation and convert it to an applicable * lambda function. */ -const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px) { +const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px, modeval::ServerConf& sc) { const string itype(elementName(impl)); if (contains(itype, ".python")) - return modpython::evalImplementation(path, impl, px); + return modpython::evalImplementation(path, impl, px, sc); if (contains(itype, ".cpp")) - return modcpp::evalImplementation(path, impl, px); + return modcpp::evalImplementation(path, impl, px, sc); return mkfailure<lambda<value(const list<value>&)> >(string("Unsupported implementation type: ") + itype); } diff --git a/sca-cpp/trunk/modules/python/mod-python.hpp b/sca-cpp/trunk/modules/python/mod-python.hpp index e67b9a4a93..cbe2b6b97c 100644 --- a/sca-cpp/trunk/modules/python/mod-python.hpp +++ b/sca-cpp/trunk/modules/python/mod-python.hpp @@ -34,7 +34,7 @@ #include "value.hpp" #include "monad.hpp" #include "eval.hpp" -#include "../http/httpd.hpp" +#include "../server/mod-eval.hpp" namespace tuscany { namespace server { @@ -63,7 +63,7 @@ struct applyImplementation { * Evaluate a Python component implementation and convert it to an applicable * lambda function. */ -const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px) { +const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px, unused modeval::ServerConf& sc) { const string fpath(path + attributeValue("script", impl)); ifstream is(fpath); if (fail(is)) diff --git a/sca-cpp/trunk/modules/python/python-test.cpp b/sca-cpp/trunk/modules/python/python-test.cpp index 48687fa0ec..c4ffcee57e 100644 --- a/sca-cpp/trunk/modules/python/python-test.cpp +++ b/sca-cpp/trunk/modules/python/python-test.cpp @@ -37,6 +37,7 @@ const string testPythonAdd = bool testEvalExpr() { gc_scoped_pool pool; + PythonRuntime py; istringstream is(testPythonAdd); failable<PyObject*> script = readScript("script", is); @@ -69,6 +70,7 @@ const string testCallLambda( bool testEvalLambda() { gc_scoped_pool pool; + PythonRuntime py; const value trl = mklist<value>("testReturnLambda"); istringstream trlis(testReturnLambda); diff --git a/sca-cpp/trunk/modules/python/server-test b/sca-cpp/trunk/modules/python/server-test index 247734e63d..fe1ff7a486 100755 --- a/sca-cpp/trunk/modules/python/server-test +++ b/sca-cpp/trunk/modules/python/server-test @@ -22,14 +22,11 @@ ../server/server-conf tmp ./python-conf tmp cat >>tmp/conf/httpd.conf <<EOF - -<Location /> SCAContribution `pwd`/ SCAComposite domain-test.composite -</Location> EOF -apachectl -k start -d `pwd`/tmp +../http/httpd-start tmp sleep 2 # Test @@ -37,6 +34,6 @@ sleep 2 rc=$? # Cleanup -apachectl -k stop -d `pwd`/tmp +../http/httpd-stop tmp sleep 2 return $rc diff --git a/sca-cpp/trunk/modules/python/wiring-test b/sca-cpp/trunk/modules/python/wiring-test index 96306ace28..a3c85838fd 100755 --- a/sca-cpp/trunk/modules/python/wiring-test +++ b/sca-cpp/trunk/modules/python/wiring-test @@ -24,14 +24,11 @@ echo "Testing..." ../server/server-conf tmp ./python-conf tmp cat >>tmp/conf/httpd.conf <<EOF - -<Location /> SCAContribution `pwd`/ SCAComposite domain-test.composite -</Location> EOF -apachectl -k start -d `pwd`/tmp +../http/httpd-start tmp sleep 2 # Test HTTP GET @@ -71,7 +68,7 @@ if [ "$rc" = "0" ]; then fi # Cleanup -apachectl -k stop -d `pwd`/tmp +../http/httpd-stop tmp sleep 2 if [ "$rc" = "0" ]; then echo "OK" diff --git a/sca-cpp/trunk/modules/scheme/primitive.hpp b/sca-cpp/trunk/modules/scheme/primitive.hpp index f1396710f5..5a13725ffd 100644 --- a/sca-cpp/trunk/modules/scheme/primitive.hpp +++ b/sca-cpp/trunk/modules/scheme/primitive.hpp @@ -171,6 +171,18 @@ const value cdddrProc(unused const list<value>& args) { return cdddr((list<value> )car(args)); } +const value startProc(unused const list<value>& args) { + return false; +} + +const value stopProc(unused const list<value>& args) { + return false; +} + +const value restartProc(unused const list<value>& args) { + return false; +} + const value applyPrimitiveProcedure(const value& proc, list<value>& args) { const lambda<value(const list<value>&)> func(cadr((list<value>)proc)); return func(args); @@ -222,7 +234,10 @@ const list<value> primitiveProcedureNames() { + "cdddr" + "display" + "log" - + "uuid"; + + "uuid" + + "start" + + "stop" + + "restart"; } const list<value> primitiveProcedureObjects() { @@ -245,7 +260,10 @@ const list<value> primitiveProcedureObjects() { + primitiveProcedure(cdddrProc) + primitiveProcedure(displayProc) + primitiveProcedure(logProc) - + primitiveProcedure(uuidProc); + + primitiveProcedure(uuidProc) + + primitiveProcedure(startProc) + + primitiveProcedure(stopProc) + + primitiveProcedure(restartProc); } const bool isFalse(const value& exp) { diff --git a/sca-cpp/trunk/modules/server/httpd-test b/sca-cpp/trunk/modules/server/httpd-test index 79651c8351..86718f96c5 100755 --- a/sca-cpp/trunk/modules/server/httpd-test +++ b/sca-cpp/trunk/modules/server/httpd-test @@ -24,14 +24,11 @@ echo "Testing..." ./server-conf tmp ./scheme-conf tmp cat >>tmp/conf/httpd.conf <<EOF - -<Location /> SCAContribution `pwd`/ SCAComposite domain-test.composite -</Location> EOF -apachectl -k start -d `pwd`/tmp +../http/httpd-start tmp sleep 2 # Test HTTP GET @@ -71,7 +68,7 @@ if [ "$rc" = "0" ]; then fi # Cleanup -apachectl -k stop -d `pwd`/tmp +../http/httpd-stop tmp sleep 2 if [ "$rc" = "0" ]; then echo "OK" diff --git a/sca-cpp/trunk/modules/server/impl-test.cpp b/sca-cpp/trunk/modules/server/impl-test.cpp index 748e5f3837..51162d070d 100644 --- a/sca-cpp/trunk/modules/server/impl-test.cpp +++ b/sca-cpp/trunk/modules/server/impl-test.cpp @@ -70,7 +70,7 @@ const tuscany::value apply(const tuscany::list<tuscany::value>& params) { return tuscany::server::del(cdr(params)); if (func == "echo") return tuscany::server::echo(cdr(params)); - return tuscany::mkfailure<tuscany::value>(tuscany::string("Function not supported: ") + func); + return tuscany::mkfailure<tuscany::value>(); } } diff --git a/sca-cpp/trunk/modules/server/mod-cpp.hpp b/sca-cpp/trunk/modules/server/mod-cpp.hpp index f10b91dc28..19ba938034 100644 --- a/sca-cpp/trunk/modules/server/mod-cpp.hpp +++ b/sca-cpp/trunk/modules/server/mod-cpp.hpp @@ -37,7 +37,7 @@ #include "monad.hpp" #include "dynlib.hpp" #include "../scheme/driver.hpp" -#include "../http/httpd.hpp" +#include "mod-eval.hpp" namespace tuscany { namespace server { @@ -46,6 +46,21 @@ namespace modcpp { /** * Apply a C++ component implementation function. */ +const list<value> failableResult(const value& func, const list<value>& v) { + if (isNil(cdr(v))) + return v; + + // Report a failure with an empty reason as 'function not supported' + // Except for the start, stop, and restart functions, which are optional + const value reason = cadr(v); + if (length(reason) == 0) { + if (func == "start" || func == "stop" || func == "restart") + return mklist<value>(false); + return mklist<value>(value(), string("Function not supported: ") + func); + } + return v; +} + struct applyImplementation { const lib ilib; const lambda<value(const list<value>&)> impl; @@ -54,7 +69,10 @@ struct applyImplementation { } const value operator()(const list<value>& params) const { debug(params, "modeval::cpp::applyImplementation::input"); - const value val = impl(append(params, px)); + + // Apply the component implementation function + const value val = failableResult(car(params), impl(append(params, px))); + debug(val, "modeval::cpp::applyImplementation::result"); return val; } @@ -64,7 +82,9 @@ struct applyImplementation { * Evaluate a C++ component implementation and convert it to * an applicable lambda function. */ -const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px) { +const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px, unused modeval::ServerConf& sc) { + + // Configure the implementation's lambda function const value ipath(attributeValue("path", impl)); const value iname(attributeValue("library", impl)); const string fpath(isNil(ipath)? path + iname : path + ipath + "/" + iname); @@ -72,7 +92,8 @@ const failable<lambda<value(const list<value>&)> > evalImplementation(const stri const failable<lambda<value(const list<value>&)> > evalf(dynlambda<value(const list<value>&)>("apply", ilib)); if (!hasContent(evalf)) return evalf; - return lambda<value(const list<value>&)>(applyImplementation(ilib, content(evalf), px)); + const lambda<value(const list<value>&)> l(applyImplementation(ilib, content(evalf), px)); + return l; } } diff --git a/sca-cpp/trunk/modules/server/mod-eval.cpp b/sca-cpp/trunk/modules/server/mod-eval.cpp index 54ca171ec4..5a9b87ca2f 100644 --- a/sca-cpp/trunk/modules/server/mod-eval.cpp +++ b/sca-cpp/trunk/modules/server/mod-eval.cpp @@ -37,15 +37,36 @@ namespace server { namespace modeval { /** + * Start the module. + */ +const failable<bool> start(unused ServerConf& sc) { + return true; +} + +/** + * Stop the module. + */ +const failable<bool> stop(unused ServerConf& sc) { + return true; +} + +/** + * Restart the module. + */ +const failable<bool> restart(unused ServerConf& sc) { + return true; +} + +/** * Evaluate a Scheme or C++ component implementation and convert it to an * applicable lambda function. */ -const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px) { +const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px, ServerConf& sc) { const string itype(elementName(impl)); if (contains(itype, ".scheme")) - return modscheme::evalImplementation(path, impl, px); + return modscheme::evalImplementation(path, impl, px, sc); if (contains(itype, ".cpp")) - return modcpp::evalImplementation(path, impl, px); + return modcpp::evalImplementation(path, impl, px, sc); return mkfailure<lambda<value(const list<value>&)> >(string("Unsupported implementation type: ") + itype); } diff --git a/sca-cpp/trunk/modules/server/mod-eval.hpp b/sca-cpp/trunk/modules/server/mod-eval.hpp index b622283fed..0e68e63016 100644 --- a/sca-cpp/trunk/modules/server/mod-eval.hpp +++ b/sca-cpp/trunk/modules/server/mod-eval.hpp @@ -19,6 +19,9 @@ /* $Rev$ $Date$ */ +#ifndef tuscany_modeval_hpp +#define tuscany_modeval_hpp + /** * HTTPD module used to eval component implementations. */ @@ -50,22 +53,13 @@ namespace modeval { */ class ServerConf { public: - ServerConf(server_rec* s) : s(s), home(""), wiringServerName("") { + ServerConf(server_rec* s) : s(s), moduleConf(NULL), home(""), wiringServerName(""), contributionPath(""), compositeName("") { } const server_rec* s; + void* moduleConf; string home; string wiringServerName; -}; - -/** - * Directory configuration. - */ -class DirConf { -public: - DirConf(char* dirspec) : dirspec(dirspec), contributionPath(""), compositeName("") { - } - const char* dirspec; string contributionPath; string compositeName; list<value> implementations; @@ -262,9 +256,9 @@ int handler(request_rec *r) { httpdDebugRequest(r, "modeval::handler::input"); // Get the component implementation lambda - DirConf& dc = httpd::dirConf<DirConf>(r, &mod_tuscany_eval); + const ServerConf& sc = httpd::serverConf<ServerConf>(r, &mod_tuscany_eval); const list<value> path(httpd::pathValues(r->uri)); - const list<value> impl(assoctree<value>(cadr(path), dc.implementations)); + const list<value> impl(assoctree<value>(cadr(path), sc.implementations)); if (isNil(impl)) return HTTP_NOT_FOUND; @@ -322,8 +316,8 @@ const list<value> propProxies(const list<value>& props) { /** * Evaluate a component and convert it to an applicable lambda function. */ -const value evalComponent(DirConf& dc, ServerConf& sc, server_rec& server, const value& comp) { - extern const failable<lambda<value(const list<value>&)> > evalImplementation(const string& cpath, const value& impl, const list<value>& px); +const value evalComponent(ServerConf& sc, server_rec& server, const value& comp) { + extern const failable<lambda<value(const list<value>&)> > evalImplementation(const string& cpath, const value& impl, const list<value>& px, ServerConf& sc); const value impl = scdl::implementation(comp); @@ -342,23 +336,19 @@ const value evalComponent(DirConf& dc, ServerConf& sc, server_rec& server, const const list<value> ppx(propProxies(scdl::properties(comp))); // Evaluate the component implementation and convert it to an applicable lambda function - const failable<lambda<value(const list<value>&)> > cimpl(evalImplementation(dc.contributionPath, impl, append(rpx, ppx))); + const failable<lambda<value(const list<value>&)> > cimpl(evalImplementation(sc.contributionPath, impl, append(rpx, ppx), sc)); if (!hasContent(cimpl)) return reason(cimpl); return content(cimpl); } /** - * Return a tree of component-name + configured-implementation pairs. + * Return a list of component-name + configured-implementation pairs. */ -const list<value> componentToImplementationAssoc(DirConf& dc, ServerConf& sc, server_rec& server, const list<value>& c) { +const list<value> componentToImplementationAssoc(ServerConf& sc, server_rec& server, const list<value>& c) { if (isNil(c)) return c; - return cons<value>(mklist<value>(scdl::name(car(c)), evalComponent(dc, sc, server, car(c))), componentToImplementationAssoc(dc, sc, server, cdr(c))); -} - -const list<value> componentToImplementationTree(DirConf& dc, ServerConf& sc, server_rec& server, const list<value>& c) { - return mkbtree(sort(componentToImplementationAssoc(dc, sc, server, c))); + return cons<value>(mklist<value>(scdl::name(car(c)), evalComponent(sc, server, car(c))), componentToImplementationAssoc(sc, server, cdr(c))); } /** @@ -372,48 +362,73 @@ const failable<list<value> > readComponents(const string& path) { } /** - * Configure the components declared in the deployed composite. + * Apply a list of component implementations to a (start, stop or restart) lifecycle expression. */ -const bool confComponents(DirConf& dc, ServerConf& sc, server_rec& server) { - if (dc.contributionPath == "" || dc.compositeName == "") +const failable<bool> applyLifecycleExpr(const list<value> impls, const list<value>& expr) { + if (isNil(impls)) return true; - const failable<list<value> > comps = readComponents(dc.contributionPath + dc.compositeName); + + // Evaluate lifecycle expression against a component implementation lambda + const lambda<value(const list<value>&)> l(cadr<value>(car(impls))); + const failable<value> r = failableResult(l(expr)); + if (!hasContent(r)) + return mkfailure<bool>(reason(r)); + + return applyLifecycleExpr(cdr(impls), expr); +} + +/** + * Configure the components declared in the deployed composite. + */ +const failable<bool> confComponents(const string& lifecycle, ServerConf& sc, server_rec& server) { + if (sc.contributionPath == "" || sc.compositeName == "") + return false; + + // Read the components and get their implementation lambda functions + const failable<list<value> > comps = readComponents(sc.contributionPath + sc.compositeName); if (!hasContent(comps)) - return true; - dc.implementations = componentToImplementationTree(dc, sc, server, content(comps)); - debug(dc.implementations, "modeval::confComponents::implementations"); - return true; + return mkfailure<bool>(reason(comps)); + const list<value> impls = componentToImplementationAssoc(sc, server, content(comps)); + + // Store the implementation lambda functions in a tree for fast retrieval + sc.implementations = mkbtree(sort(impls)); + debug(sc.implementations, "modeval::confComponents::implementations"); + + // Start or restart the component implementations + return applyLifecycleExpr(impls, mklist<value>(lifecycle)); } /** * Configuration commands. */ -const char *confHome(cmd_parms *cmd, unused void *c, const char *arg) { +const char* confHome(cmd_parms *cmd, unused void *c, const char *arg) { gc_scoped_pool pool(cmd->pool); ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_eval); sc.home = arg; return NULL; } -const char *confWiringServerName(cmd_parms *cmd, unused void *c, const char *arg) { +const char* confWiringServerName(cmd_parms *cmd, unused void *c, const char *arg) { gc_scoped_pool pool(cmd->pool); ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_eval); sc.wiringServerName = arg; return NULL; } -const char *confContribution(cmd_parms *cmd, void *c, const char *arg) { +const char* confContribution(cmd_parms *cmd, unused void *c, const char *arg) { gc_scoped_pool pool(cmd->pool); ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_eval); - DirConf& dc = *(DirConf*)c; - dc.contributionPath = arg; - confComponents(dc, sc, *cmd->server); + sc.contributionPath = arg; return NULL; } -const char *confComposite(cmd_parms *cmd, void *c, const char *arg) { +const char* confComposite(cmd_parms *cmd, unused void *c, const char *arg) { gc_scoped_pool pool(cmd->pool); ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_eval); - DirConf& dc = *(DirConf*)c; - dc.compositeName = arg; - confComponents(dc, sc, *cmd->server); + sc.compositeName = arg; + return NULL; +} + +const char* confEnv(unused cmd_parms *cmd, unused void *c, const char *name, const char *value) { + gc_scoped_pool pool(cmd->pool); + setenv(name, value != NULL? value : "", 1); return NULL; } @@ -423,15 +438,49 @@ const char *confComposite(cmd_parms *cmd, void *c, const char *arg) { const command_rec commands[] = { AP_INIT_TAKE1("TuscanyHome", (const char*(*)())confHome, NULL, RSRC_CONF, "Tuscany home directory"), AP_INIT_TAKE1("SCAWiringServerName", (const char*(*)())confWiringServerName, NULL, RSRC_CONF, "SCA wiring server name"), - AP_INIT_TAKE1("SCAContribution", (const char*(*)())confContribution, NULL, ACCESS_CONF, "SCA contribution location"), - AP_INIT_TAKE1("SCAComposite", (const char*(*)())confComposite, NULL, ACCESS_CONF, "SCA composite location"), + AP_INIT_TAKE1("SCAContribution", (const char*(*)())confContribution, NULL, RSRC_CONF, "SCA contribution location"), + AP_INIT_TAKE1("SCAComposite", (const char*(*)())confComposite, NULL, RSRC_CONF, "SCA composite location"), + AP_INIT_TAKE12("SetEnv", (const char*(*)())confEnv, NULL, OR_FILEINFO, "Environment variable name and optional value"), {NULL, NULL, NULL, 0, NO_ARGS, NULL} }; -int postConfig(unused apr_pool_t *p, unused apr_pool_t *plog, unused apr_pool_t *ptemp, unused server_rec *s) { +int postConfig(apr_pool_t *p, unused apr_pool_t *plog, unused apr_pool_t *ptemp, server_rec *s) { + extern const failable<bool> start(ServerConf& sc); + extern const failable<bool> restart(ServerConf& sc); + gc_scoped_pool pool(p); + ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_eval); + + // Count the calls to post config + const string k("tuscany::modeval::postConfig"); + const int count = httpd::userData(k, s); + httpd::putUserData(k, count +1, s); + + // Count == 0, do nothing as post config is always called twice, + // count == 1 is the first start, count > 1 is a restart + if (count == 0) + return OK; + if (count == 1) { + debug("modeval::postConfig::start"); + start(sc); + } + if (count > 1) { + debug("modeval::postConfig::restart"); + restart(sc); + } + + // Configure the components deployed to the server + debug(sc.wiringServerName, "modeval::postConfig::wiringServerName"); + debug(sc.contributionPath, "modeval::postConfig::contributionPath"); + debug(sc.compositeName, "modeval::postConfig::compositeName"); + const failable<bool> res = confComponents(count > 1? "restart" : "start", sc, *s); + if (!hasContent(res)) + return -1; return OK; } +/** + * Child process initialization. + */ void childInit(apr_pool_t* p, server_rec* svr_rec) { gc_scoped_pool pool(p); ServerConf* c = (ServerConf*)ap_get_module_config(svr_rec->module_config, &mod_tuscany_eval); @@ -457,7 +506,7 @@ extern "C" { module AP_MODULE_DECLARE_DATA mod_tuscany_eval = { STANDARD20_MODULE_STUFF, // dir config and merger - tuscany::httpd::makeDirConf<tuscany::server::modeval::DirConf>, NULL, + NULL, NULL, // server config and merger tuscany::httpd::makeServerConf<tuscany::server::modeval::ServerConf>, NULL, // commands and hooks @@ -465,3 +514,5 @@ module AP_MODULE_DECLARE_DATA mod_tuscany_eval = { }; } + +#endif diff --git a/sca-cpp/trunk/modules/server/mod-scheme.hpp b/sca-cpp/trunk/modules/server/mod-scheme.hpp index fd03ebb43e..e18eececf6 100644 --- a/sca-cpp/trunk/modules/server/mod-scheme.hpp +++ b/sca-cpp/trunk/modules/server/mod-scheme.hpp @@ -34,7 +34,7 @@ #include "value.hpp" #include "monad.hpp" #include "../scheme/eval.hpp" -#include "../http/httpd.hpp" +#include "../server/mod-eval.hpp" namespace tuscany { namespace server { @@ -73,7 +73,7 @@ struct applyImplementation { * Evaluate a Scheme component implementation and convert it to an * applicable lambda function. */ -const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px) { +const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px, unused modeval::ServerConf& sc) { const string fpath(path + attributeValue("script", impl)); ifstream is(fpath); if (fail(is)) diff --git a/sca-cpp/trunk/modules/server/mod-wiring.cpp b/sca-cpp/trunk/modules/server/mod-wiring.cpp index aef2f00c83..e21f8be773 100644 --- a/sca-cpp/trunk/modules/server/mod-wiring.cpp +++ b/sca-cpp/trunk/modules/server/mod-wiring.cpp @@ -48,11 +48,16 @@ namespace modwiring { */ class ServerConf { public: - ServerConf(server_rec* s) : s(s), home(""), wiringServerName("") { + ServerConf(server_rec* s) : s(s), start(false), home(""), wiringServerName(""), contributionPath(""), compositeName("") { } const server_rec* s; + bool start; string home; string wiringServerName; + string contributionPath; + string compositeName; + list<value> references; + list<value> services; }; /** @@ -61,20 +66,6 @@ public: const bool useModProxy = true; /** - * Directory configuration. - */ -class DirConf { -public: - DirConf(char* dirspec) : dirspec(dirspec), contributionPath(""), compositeName("") { - } - const char* dirspec; - string contributionPath; - string compositeName; - list<value> references; - list<value> services; -}; - -/** * Returns true if a URI is absolute. */ const bool isAbsolute(const string& uri) { @@ -90,9 +81,9 @@ int translateReference(request_rec *r) { debug(r->uri, "modwiring::translateReference::uri"); // Find the requested component - DirConf& dc = httpd::dirConf<DirConf>(r, &mod_tuscany_wiring); + const ServerConf& sc = httpd::serverConf<ServerConf>(r, &mod_tuscany_wiring); const list<value> rpath(httpd::pathValues(r->uri)); - const list<value> comp(assoctree(cadr(rpath), dc.references)); + const list<value> comp(assoctree(cadr(rpath), sc.references)); if (isNil(comp)) return HTTP_NOT_FOUND; @@ -155,9 +146,9 @@ int translateService(request_rec *r) { debug(r->uri, "modwiring::translateService::uri"); // Find the requested component - DirConf& dc = httpd::dirConf<DirConf>(r, &mod_tuscany_wiring); + const ServerConf& sc = httpd::serverConf<ServerConf>(r, &mod_tuscany_wiring); const list<value> path(httpd::pathValues(r->uri)); - const list<value> svc(assocPath(path, dc.services)); + const list<value> svc(assocPath(path, sc.services)); if (isNil(svc)) return DECLINED; debug(svc, "modwiring::translateService::service"); @@ -282,16 +273,19 @@ const list<value> uriToComponentTree(const list<value>& c) { /** * Configure the components declared in the server's deployment composite. */ -const bool confComponents(DirConf& dc) { - if (dc.contributionPath == "" || dc.compositeName == "") +const bool confComponents(ServerConf& sc) { + if (sc.contributionPath == "" || sc.compositeName == "") return true; - const failable<list<value> > comps = readComponents(dc.contributionPath + dc.compositeName); + + // Read the component configuration and store the references and service + // URIs in trees for fast retrieval later + const failable<list<value> > comps = readComponents(sc.contributionPath + sc.compositeName); if (!hasContent(comps)) return true; - dc.references = componentReferenceToTargetTree(content(comps)); - debug(dc.references, "modwiring::confComponents::references"); - dc.services = uriToComponentTree(content(comps)); - debug(dc.services, "modwiring::confComponents::services"); + sc.references = componentReferenceToTargetTree(content(comps)); + debug(sc.references, "modwiring::confComponents::references"); + sc.services = uriToComponentTree(content(comps)); + debug(sc.services, "modwiring::confComponents::services"); return true; } @@ -310,18 +304,16 @@ const char *confWiringServerName(cmd_parms *cmd, unused void *c, const char *arg sc.wiringServerName = arg; return NULL; } -const char *confContribution(cmd_parms *cmd, void *c, const char *arg) { +const char *confContribution(cmd_parms *cmd, unused void *c, const char *arg) { gc_scoped_pool pool(cmd->pool); - DirConf& dc = *(DirConf*)c; - dc.contributionPath = arg; - confComponents(dc); + ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_wiring); + sc.contributionPath = arg; return NULL; } -const char *confComposite(cmd_parms *cmd, void *c, const char *arg) { +const char *confComposite(cmd_parms *cmd, unused void *c, const char *arg) { gc_scoped_pool pool(cmd->pool); - DirConf& dc = *(DirConf*)c; - dc.compositeName = arg; - confComponents(dc); + ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_wiring); + sc.compositeName = arg; return NULL; } @@ -330,14 +322,28 @@ const char *confComposite(cmd_parms *cmd, void *c, const char *arg) { */ const command_rec commands[] = { AP_INIT_TAKE1("TuscanyHome", (const char*(*)())confHome, NULL, RSRC_CONF, "Tuscany home directory"), - AP_INIT_TAKE1("SCAWiringServerName", (const char*(*)())confWiringServerName, NULL, ACCESS_CONF, "SCA wiring server name"), - AP_INIT_TAKE1("SCAContribution", (const char*(*)())confContribution, NULL, ACCESS_CONF, "SCA contribution location"), - AP_INIT_TAKE1("SCAComposite", (const char*(*)())confComposite, NULL, ACCESS_CONF, "SCA composite location"), + AP_INIT_TAKE1("SCAWiringServerName", (const char*(*)())confWiringServerName, NULL, RSRC_CONF, "SCA wiring server name"), + AP_INIT_TAKE1("SCAContribution", (const char*(*)())confContribution, NULL, RSRC_CONF, "SCA contribution location"), + AP_INIT_TAKE1("SCAComposite", (const char*(*)())confComposite, NULL, RSRC_CONF, "SCA composite location"), {NULL, NULL, NULL, 0, NO_ARGS, NULL} }; -int postConfig(unused apr_pool_t *p, unused apr_pool_t *plog, unused apr_pool_t *ptemp, unused server_rec *s) { - return OK; +int postConfig(unused apr_pool_t *p, unused apr_pool_t *plog, unused apr_pool_t *ptemp, server_rec *s) { + // Count the calls to post config, skip the first one as + // postConfig is always called twice + const string k("tuscany::modwiring::postConfig"); + const int count = httpd::userData(k, s); + httpd::putUserData(k, count +1, s); + if (count == 0) + return OK; + + // Configure the wiring for the deployed components + ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_wiring); + debug(sc.wiringServerName, "modwiring::postConfig::wiringServerName"); + debug(sc.contributionPath, "modwiring::postConfig::contributionPath"); + debug(sc.compositeName, "modwiring::postConfig::compositeName"); + confComponents(sc); + return OK; } void childInit(apr_pool_t* p, server_rec* svr_rec) { @@ -365,7 +371,7 @@ extern "C" { module AP_MODULE_DECLARE_DATA mod_tuscany_wiring = { STANDARD20_MODULE_STUFF, // dir config and merger - tuscany::httpd::makeDirConf<tuscany::server::modwiring::DirConf>, NULL, + NULL, NULL, // server config and merger tuscany::httpd::makeServerConf<tuscany::server::modwiring::ServerConf>, NULL, // commands and hooks diff --git a/sca-cpp/trunk/modules/server/server-test b/sca-cpp/trunk/modules/server/server-test index 97b3fd919b..e1d9932a5d 100755 --- a/sca-cpp/trunk/modules/server/server-test +++ b/sca-cpp/trunk/modules/server/server-test @@ -22,14 +22,11 @@ ./server-conf tmp ./scheme-conf tmp cat >>tmp/conf/httpd.conf <<EOF - -<Location /> SCAContribution `pwd`/ SCAComposite domain-test.composite -</Location> EOF -apachectl -k start -d `pwd`/tmp +../http/httpd-start tmp sleep 2 # Test @@ -37,6 +34,6 @@ sleep 2 rc=$? # Cleanup -apachectl -k stop -d `pwd`/tmp +../http/httpd-stop tmp sleep 2 return $rc diff --git a/sca-cpp/trunk/modules/server/wiring-test b/sca-cpp/trunk/modules/server/wiring-test index 29eef996e6..0deab33d68 100755 --- a/sca-cpp/trunk/modules/server/wiring-test +++ b/sca-cpp/trunk/modules/server/wiring-test @@ -24,14 +24,11 @@ echo "Testing..." ./server-conf tmp ./scheme-conf tmp cat >>tmp/conf/httpd.conf <<EOF - -<Location /> SCAContribution `pwd`/ SCAComposite domain-test.composite -</Location> EOF -apachectl -k start -d `pwd`/tmp +../http/httpd-start tmp sleep 2 # Test HTTP GET @@ -71,7 +68,7 @@ if [ "$rc" = "0" ]; then fi # Cleanup -apachectl -k stop -d `pwd`/tmp +../http/httpd-stop tmp sleep 2 if [ "$rc" = "0" ]; then echo "OK" diff --git a/sca-cpp/trunk/test/store-cpp/currency-converter.cpp b/sca-cpp/trunk/test/store-cpp/currency-converter.cpp index a48fd46021..5f0702490a 100644 --- a/sca-cpp/trunk/test/store-cpp/currency-converter.cpp +++ b/sca-cpp/trunk/test/store-cpp/currency-converter.cpp @@ -61,7 +61,7 @@ const tuscany::value apply(const tuscany::list<tuscany::value>& params) { return tuscany::store::convert(cadr(params), caddr(params), cadddr(params)); if (func == "symbol") return tuscany::store::symbol(cadr(params)); - return tuscany::mkfailure<tuscany::value>(tuscany::string("Function not supported: ") + func); + return tuscany::mkfailure<tuscany::value>(); } } diff --git a/sca-cpp/trunk/test/store-cpp/fruits-catalog.cpp b/sca-cpp/trunk/test/store-cpp/fruits-catalog.cpp index f0c9472177..20f2bd35f7 100644 --- a/sca-cpp/trunk/test/store-cpp/fruits-catalog.cpp +++ b/sca-cpp/trunk/test/store-cpp/fruits-catalog.cpp @@ -79,7 +79,7 @@ const tuscany::value apply(const tuscany::list<tuscany::value>& params) { return tuscany::store::get(cadr(params), caddr(params)); if (func == "listMethods") return tuscany::store::listMethods(cadr(params), caddr(params)); - return tuscany::mkfailure<tuscany::value>(tuscany::string("Function not supported: ") + func); + return tuscany::mkfailure<tuscany::value>(); } } diff --git a/sca-cpp/trunk/test/store-cpp/shopping-cart.cpp b/sca-cpp/trunk/test/store-cpp/shopping-cart.cpp index 072c90512f..5dcbc88ee9 100644 --- a/sca-cpp/trunk/test/store-cpp/shopping-cart.cpp +++ b/sca-cpp/trunk/test/store-cpp/shopping-cart.cpp @@ -157,7 +157,7 @@ const tuscany::value apply(const tuscany::list<tuscany::value>& params) { return tuscany::store::gettotal(cadr(params)); if (func == "listMethods") return tuscany::store::listMethods(cadr(params)); - return tuscany::mkfailure<tuscany::value>(tuscany::string("Function not supported: ") + func); + return tuscany::mkfailure<tuscany::value>(); } } diff --git a/sca-cpp/trunk/test/store-cpp/start b/sca-cpp/trunk/test/store-cpp/start index 982aca812b..06410aca01 100755 --- a/sca-cpp/trunk/test/store-cpp/start +++ b/sca-cpp/trunk/test/store-cpp/start @@ -21,14 +21,11 @@ ../../modules/server/server-conf tmp ../../modules/server/cpp-conf tmp cat >>tmp/conf/httpd.conf <<EOF - -<Location /> SCAContribution `pwd`/ SCAComposite store.composite -</Location> EOF -apachectl -k start -d `pwd`/tmp +../../modules/http/httpd-start tmp mc="memcached -l 127.0.0.1 -m 4 -p 11211" $mc & diff --git a/sca-cpp/trunk/test/store-cpp/stop b/sca-cpp/trunk/test/store-cpp/stop index 34731dbbe1..07231ee7ce 100755 --- a/sca-cpp/trunk/test/store-cpp/stop +++ b/sca-cpp/trunk/test/store-cpp/stop @@ -17,7 +17,7 @@ # specific language governing permissions and limitations # under the License. -apachectl -k stop -d `pwd`/tmp +../../modules/http/httpd-stop tmp mc="memcached -l 127.0.0.1 -m 4 -p 11211" kill `ps -f | grep -v grep | grep "$mc" | awk '{ print $2 }'` diff --git a/sca-cpp/trunk/test/store-java/start b/sca-cpp/trunk/test/store-java/start index 43a2b90c2a..3f669f0111 100755 --- a/sca-cpp/trunk/test/store-java/start +++ b/sca-cpp/trunk/test/store-java/start @@ -21,16 +21,13 @@ ../../modules/server/server-conf tmp ../../modules/java/java-conf tmp cat >>tmp/conf/httpd.conf <<EOF - -<Location /> SCAContribution `pwd`/ SCAComposite store.composite -</Location> EOF export CLASSPATH=`pwd`/../../modules/java/libmod-tuscany-java-1.0.jar:`pwd` -apachectl -k start -d `pwd`/tmp +../../modules/http/httpd-start tmp mc="memcached -l 127.0.0.1 -m 4 -p 11211" $mc & diff --git a/sca-cpp/trunk/test/store-java/stop b/sca-cpp/trunk/test/store-java/stop index 3c4f59e76e..54b22172bb 100755 --- a/sca-cpp/trunk/test/store-java/stop +++ b/sca-cpp/trunk/test/store-java/stop @@ -19,7 +19,7 @@ export CLASSPATH=`pwd`/../../modules/java/libmod-tuscany-java-1.0.jar:`pwd` -apachectl -k stop -d `pwd`/tmp +../../modules/http/httpd-stop tmp mc="memcached -l 127.0.0.1 -m 4 -p 11211" kill `ps -f | grep -v grep | grep "$mc" | awk '{ print $2 }'` diff --git a/sca-cpp/trunk/test/store-python/start b/sca-cpp/trunk/test/store-python/start index 9e85a84cb4..33758b75fd 100755 --- a/sca-cpp/trunk/test/store-python/start +++ b/sca-cpp/trunk/test/store-python/start @@ -21,14 +21,11 @@ ../../modules/server/server-conf tmp ../../modules/python/python-conf tmp cat >>tmp/conf/httpd.conf <<EOF - -<Location /> SCAContribution `pwd`/ SCAComposite store.composite -</Location> EOF -apachectl -k start -d `pwd`/tmp +../../modules/http/httpd-start tmp mc="memcached -l 127.0.0.1 -m 4 -p 11211" $mc & diff --git a/sca-cpp/trunk/test/store-python/stop b/sca-cpp/trunk/test/store-python/stop index 34731dbbe1..07231ee7ce 100755 --- a/sca-cpp/trunk/test/store-python/stop +++ b/sca-cpp/trunk/test/store-python/stop @@ -17,7 +17,7 @@ # specific language governing permissions and limitations # under the License. -apachectl -k stop -d `pwd`/tmp +../../modules/http/httpd-stop tmp mc="memcached -l 127.0.0.1 -m 4 -p 11211" kill `ps -f | grep -v grep | grep "$mc" | awk '{ print $2 }'` diff --git a/sca-cpp/trunk/test/store-scheme/start b/sca-cpp/trunk/test/store-scheme/start index cc0ec9b5ea..398e21c8e4 100755 --- a/sca-cpp/trunk/test/store-scheme/start +++ b/sca-cpp/trunk/test/store-scheme/start @@ -21,14 +21,11 @@ ../../modules/server/server-conf tmp ../../modules/server/scheme-conf tmp cat >>tmp/conf/httpd.conf <<EOF - -<Location /> SCAContribution `pwd`/ SCAComposite store.composite -</Location> EOF -apachectl -k start -d `pwd`/tmp +../../modules/http/httpd-start tmp mc="memcached -l 127.0.0.1 -m 4 -p 11211" $mc & diff --git a/sca-cpp/trunk/test/store-scheme/stop b/sca-cpp/trunk/test/store-scheme/stop index 34731dbbe1..07231ee7ce 100755 --- a/sca-cpp/trunk/test/store-scheme/stop +++ b/sca-cpp/trunk/test/store-scheme/stop @@ -17,7 +17,7 @@ # specific language governing permissions and limitations # under the License. -apachectl -k stop -d `pwd`/tmp +../../modules/http/httpd-stop tmp mc="memcached -l 127.0.0.1 -m 4 -p 11211" kill `ps -f | grep -v grep | grep "$mc" | awk '{ print $2 }'` |