diff options
author | jsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68> | 2010-08-29 03:19:48 +0000 |
---|---|---|
committer | jsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68> | 2010-08-29 03:19:48 +0000 |
commit | 163a913a226cca335544231da5051562891c286b (patch) | |
tree | d7a3dbe8f0866575a356966a39a389396011f54c /sca-cpp | |
parent | 88bf2a256b02e1858993bf097f4dc743d389e3f0 (diff) |
Make sure components execute in the correct contribution directory and fix support for Python relative module imports.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@990483 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sca-cpp')
-rw-r--r-- | sca-cpp/trunk/kernel/kernel-test.cpp | 9 | ||||
-rw-r--r-- | sca-cpp/trunk/kernel/sstream.hpp | 18 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/python/driver.hpp | 2 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/python/eval.hpp | 16 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/python/mod-python.hpp | 5 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/python/python-test.cpp | 2 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/server/mod-eval.hpp | 46 |
7 files changed, 72 insertions, 26 deletions
diff --git a/sca-cpp/trunk/kernel/kernel-test.cpp b/sca-cpp/trunk/kernel/kernel-test.cpp index 0096a9d6e3..9b87397b96 100644 --- a/sca-cpp/trunk/kernel/kernel-test.cpp +++ b/sca-cpp/trunk/kernel/kernel-test.cpp @@ -275,11 +275,20 @@ bool testZip() { } bool testTokenize() { + assert(tokenize("/", "") == list<string>()); + assert(tokenize("/", "aaa") == mklist<string>("aaa")); assert(tokenize("/", "aaa/bbb/ccc/ddd") == mklist<string>("aaa", "bbb", "ccc", "ddd")); assert(tokenize("/", "/bbb/ccc/ddd") == mklist<string>("", "bbb", "ccc", "ddd")); assert(tokenize("/", "/bbb/ccc/") == mklist<string>("", "bbb", "ccc")); assert(tokenize("/", "/bbb//ccc/") == mklist<string>("", "bbb", "", "ccc")); assert(tokenize("/", "abc/def/") == mklist<string>("abc", "def")); + + assert(join("/", list<string>()) == ""); + assert(join("/", mklist<string>("aaa")) == "aaa"); + assert(join("/", mklist<string>("aaa", "bbb", "ccc", "ddd")) == "aaa/bbb/ccc/ddd"); + assert(join("/", mklist<string>("", "bbb", "ccc", "ddd")) == "/bbb/ccc/ddd"); + assert(join("/", mklist<string>("bbb", "ccc", "")) == "bbb/ccc/"); + assert(join("/", mklist<string>("bbb", "", "ccc")) == "bbb//ccc"); return true; } diff --git a/sca-cpp/trunk/kernel/sstream.hpp b/sca-cpp/trunk/kernel/sstream.hpp index f5006606dd..693ba5f88f 100644 --- a/sca-cpp/trunk/kernel/sstream.hpp +++ b/sca-cpp/trunk/kernel/sstream.hpp @@ -196,6 +196,24 @@ const list<string> tokenize(const char* sep, const string& str) { } /** + * Join a list of strings into a single string. + */ +const string join(const char* sep, const list<string>& l) { + struct nested { + static ostringstream& join(const char* sep, const list<string>& l, ostringstream& os) { + if (isNil(l)) + return os; + os << car(l); + if (!isNil(cdr(l))) + os << sep; + return join(sep, cdr(l), os); + } + }; + ostringstream os; + return str(nested::join(sep, l, os)); +} + +/** * Returns a lazy list view of an input stream. */ struct ilistRead{ diff --git a/sca-cpp/trunk/modules/python/driver.hpp b/sca-cpp/trunk/modules/python/driver.hpp index 2820201057..79897b0c5e 100644 --- a/sca-cpp/trunk/modules/python/driver.hpp +++ b/sca-cpp/trunk/modules/python/driver.hpp @@ -50,7 +50,7 @@ const bool evalDriverRun(const char* path, istream& in, ostream& out) { PythonRuntime py; scheme::setupDisplay(out); ifstream is(path); - failable<PyObject*> script = readScript(path, is); + failable<PyObject*> script = readScript(moduleName(path), path, is); if (!hasContent(script)) return true; evalDriverLoop(content(script), in, out); diff --git a/sca-cpp/trunk/modules/python/eval.hpp b/sca-cpp/trunk/modules/python/eval.hpp index 855804a5ae..daccb16ec7 100644 --- a/sca-cpp/trunk/modules/python/eval.hpp +++ b/sca-cpp/trunk/modules/python/eval.hpp @@ -42,6 +42,8 @@ public: if (Py_IsInitialized()) return; Py_InitializeEx(0); + const char* arg0 = ""; + PySys_SetArgv(0, const_cast<char**>(&arg0)); } }; @@ -133,7 +135,6 @@ PyObject *mkPyLambda(const lambda<value(const list<value>&)>& l) { /** * Convert a list of values to a python list. */ - PyObject* valuesToPyListHelper(PyObject* l, const list<value>& v) { if (isNil(v)) return l; @@ -231,6 +232,13 @@ const value pyObjectToValue(PyObject *o) { } /** + * Convert a python script path to a module name. + */ +const string moduleName(const string& path) { + return join(".", tokenize("/", substr(path, 0, length(path) -3))); +} + +/** * Evaluate an expression against a script provided as a python object. */ const failable<value> evalScript(const value& expr, PyObject* script) { @@ -272,14 +280,14 @@ const failable<value> evalScript(const value& expr, PyObject* script) { /** * Read a python script from an input stream. */ -const failable<PyObject*> readScript(const string& path, istream& is) { +const failable<PyObject*> readScript(const string& name, const string& path, istream& is) { const list<string> ls = streamList(is); ostringstream os; write(ls, os); PyObject* code = Py_CompileStringFlags(c_str(str(os)), c_str(path), Py_file_input, NULL); if (code == NULL) return mkfailure<PyObject*>(string("Couldn't compile script: ") + path + " : " + lastError()); - PyObject* mod = PyImport_ExecCodeModule(const_cast<char*>(c_str(path)), code); + PyObject* mod = PyImport_ExecCodeModuleEx(const_cast<char*>(c_str(name)), code, const_cast<char*>(c_str(path))); if (mod == NULL) return mkfailure<PyObject*>(string("Couldn't import module: ") + path + " : " + lastError()); return mod; @@ -289,7 +297,7 @@ const failable<PyObject*> readScript(const string& path, istream& is) { * Evaluate an expression against a script provided as an input stream. */ const failable<value> evalScript(const value& expr, istream& is) { - failable<PyObject*> script = readScript("script", is); + failable<PyObject*> script = readScript("script", "script.py", is); if (!hasContent(script)) return mkfailure<value>(reason(script)); return evalScript(expr, content(script)); diff --git a/sca-cpp/trunk/modules/python/mod-python.hpp b/sca-cpp/trunk/modules/python/mod-python.hpp index d13f2227ab..0121779530 100644 --- a/sca-cpp/trunk/modules/python/mod-python.hpp +++ b/sca-cpp/trunk/modules/python/mod-python.hpp @@ -62,11 +62,12 @@ struct applyImplementation { * lambda function. */ const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px) { - const string fpath(path + attributeValue("script", impl)); + const string spath(attributeValue("script", impl)); + const string fpath(path + spath); ifstream is(fpath); if (fail(is)) return mkfailure<lambda<value(const list<value>&)> >(string("Could not read implementation: ") + fpath); - const failable<PyObject*> script = python::readScript(fpath, is); + const failable<PyObject*> script = python::readScript(python::moduleName(spath), fpath, is); if (!hasContent(script)) return mkfailure<lambda<value(const list<value>&)> >(reason(script)); return lambda<value(const list<value>&)>(applyImplementation(content(script), px)); diff --git a/sca-cpp/trunk/modules/python/python-test.cpp b/sca-cpp/trunk/modules/python/python-test.cpp index c4ffcee57e..41889e6d0e 100644 --- a/sca-cpp/trunk/modules/python/python-test.cpp +++ b/sca-cpp/trunk/modules/python/python-test.cpp @@ -40,7 +40,7 @@ bool testEvalExpr() { PythonRuntime py; istringstream is(testPythonAdd); - failable<PyObject*> script = readScript("script", is); + failable<PyObject*> script = readScript("script", "script.py", is); assert(hasContent(script)); const value exp = mklist<value>("add", 2, 3); diff --git a/sca-cpp/trunk/modules/server/mod-eval.hpp b/sca-cpp/trunk/modules/server/mod-eval.hpp index e573d9a1fd..95c3d7cd09 100644 --- a/sca-cpp/trunk/modules/server/mod-eval.hpp +++ b/sca-cpp/trunk/modules/server/mod-eval.hpp @@ -502,10 +502,6 @@ const failable<bool> confComponents(ServerConf& sc) { if (sc.cert != "") debug(sc.cert, "modeval::confComponents::sslCert"); if (sc.key != "") debug(sc.key, "modeval::confComponents::sslKey"); - // Chdir to the deployed contribution - if (chdir(c_str(sc.contributionPath)) != 0) - return mkfailure<bool>("Couldn't chdir to the deployed contribution"); - // Read the components and get their implementation lambda functions const failable<list<value> > comps = readComponents(sc.contributionPath + sc.compositeName); if (!hasContent(comps)) @@ -535,27 +531,27 @@ const failable<bool> startComponents(ServerConf& sc) { */ class VirtualHostConf { public: - VirtualHostConf(const gc_pool& p, const ServerConf& ssc) : sc(pool(p), ssc.server) { - sc.virtualHostContributionPath = ssc.virtualHostContributionPath; - sc.virtualHostCompositeName = ssc.virtualHostCompositeName; - sc.ca = ssc.ca; - sc.cert = ssc.cert; - sc.key = ssc.key; + VirtualHostConf(const gc_pool& p, const ServerConf& sc) : sc(sc), vsc(pool(p), sc.server) { + vsc.virtualHostContributionPath = sc.virtualHostContributionPath; + vsc.virtualHostCompositeName = sc.virtualHostCompositeName; + vsc.ca = sc.ca; + vsc.cert = sc.cert; + vsc.key = sc.key; } ~VirtualHostConf() { - extern const failable<bool> virtualHostCleanup(const ServerConf& sc); - virtualHostCleanup(sc); + extern const failable<bool> virtualHostCleanup(const ServerConf& vsc, const ServerConf& sc); + virtualHostCleanup(vsc, sc); } - ServerConf sc; + const ServerConf& sc; + ServerConf vsc; }; /** * Configure and start the components deployed in a virtual host. */ const failable<bool> virtualHostConfig(ServerConf& vsc, const ServerConf& sc, request_rec* r) { - extern const value applyLifecycle(const list<value>&); // Determine the server name and wiring server name debug(httpd::serverName(vsc.server), "modeval::virtualHostConfig::serverName"); @@ -569,6 +565,10 @@ const failable<bool> virtualHostConfig(ServerConf& vsc, const ServerConf& sc, re vsc.contributionPath = vsc.virtualHostContributionPath + httpd::subdomain(httpd::hostName(r)) + "/"; vsc.compositeName = vsc.virtualHostCompositeName; + // Chdir to the virtual host's contribution + if (chdir(c_str(sc.contributionPath)) != 0) + return mkfailure<bool>("Couldn't chdir to the deployed contribution"); + // Configure the deployed components const failable<bool> cr = confComponents(vsc); if (!hasContent(cr)) @@ -588,13 +588,17 @@ const failable<bool> virtualHostConfig(ServerConf& vsc, const ServerConf& sc, re /** * Cleanup a virtual host. */ -const failable<bool> virtualHostCleanup(const ServerConf& vsc) { +const failable<bool> virtualHostCleanup(const ServerConf& vsc, const ServerConf& sc) { if (!hasCompositeConf(vsc)) return true; debug("modeval::virtualHostCleanup"); // Stop the component implementations applyLifecycleExpr(vsc.implementations, mklist<value>("stop")); + + // Chdir back to the main server's contribution + if (chdir(c_str(sc.contributionPath)) != 0) + return mkfailure<bool>("Couldn't chdir to the deployed contribution"); return true; } @@ -616,16 +620,16 @@ int handler(request_rec *r) { // Process dynamic virtual host configuration, if any VirtualHostConf vhc(gc_pool(r->pool), sc); - const bool usevh = hasVirtualCompositeConf(vhc.sc) && httpd::isVirtualHostRequest(sc.server, r); + const bool usevh = hasVirtualCompositeConf(vhc.vsc) && httpd::isVirtualHostRequest(sc.server, r); if (usevh) { - const failable<bool> cr = virtualHostConfig(vhc.sc, sc, r); + const failable<bool> cr = virtualHostConfig(vhc.vsc, sc, r); if (!hasContent(cr)) return httpd::reportStatus(mkfailure<int>(reason(cr))); } // Get the component implementation lambda const list<value> path(pathValues(r->uri)); - const list<value> impl(assoctree<value>(cadr(path), usevh? vhc.sc.implTree : sc.implTree)); + const list<value> impl(assoctree<value>(cadr(path), usevh? vhc.vsc.implTree : sc.implTree)); if (isNil(impl)) return httpd::reportStatus(mkfailure<int>(string("Couldn't find component implementation: ") + cadr(path))); @@ -710,6 +714,12 @@ int postConfig(apr_pool_t *p, unused apr_pool_t *plog, unused apr_pool_t *ptemp, return OK; if (count == 1) { + // Chdir to the deployed contribution + if (chdir(c_str(sc.contributionPath)) != 0) { + mkfailure<bool>("Couldn't chdir to the deployed contribution"); + return -1; + } + debug("modeval::postConfig::start"); const failable<value> r = failableResult(applyLifecycle(mklist<value>("start"))); if (!hasContent(r)) |