summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2010-08-29 03:19:48 +0000
committerjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2010-08-29 03:19:48 +0000
commit163a913a226cca335544231da5051562891c286b (patch)
treed7a3dbe8f0866575a356966a39a389396011f54c
parent88bf2a256b02e1858993bf097f4dc743d389e3f0 (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
-rw-r--r--sca-cpp/trunk/kernel/kernel-test.cpp9
-rw-r--r--sca-cpp/trunk/kernel/sstream.hpp18
-rw-r--r--sca-cpp/trunk/modules/python/driver.hpp2
-rw-r--r--sca-cpp/trunk/modules/python/eval.hpp16
-rw-r--r--sca-cpp/trunk/modules/python/mod-python.hpp5
-rw-r--r--sca-cpp/trunk/modules/python/python-test.cpp2
-rw-r--r--sca-cpp/trunk/modules/server/mod-eval.hpp46
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))