summaryrefslogtreecommitdiffstats
path: root/sca-cpp/trunk/modules
diff options
context:
space:
mode:
authorjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2009-11-30 08:36:32 +0000
committerjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2009-11-30 08:36:32 +0000
commitff124040623879bc48a0ba5cf06a841642adef53 (patch)
treee0bee552780b0852c10744017b7826b08f57d377 /sca-cpp/trunk/modules
parentcd7dae28b034deebc9c2c2469ed9d8f1f3dab1ed (diff)
Fixes to the http client, httpd modules and memcached component to get the store and shopping cart test case working end to end.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@885349 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to '')
-rw-r--r--sca-cpp/trunk/modules/atom/atom.hpp14
-rw-r--r--sca-cpp/trunk/modules/http/curl-test.cpp6
-rw-r--r--sca-cpp/trunk/modules/http/curl.hpp166
-rwxr-xr-xsca-cpp/trunk/modules/http/http-test2
-rwxr-xr-xsca-cpp/trunk/modules/http/httpd-test2
-rw-r--r--sca-cpp/trunk/modules/http/httpd.hpp91
-rw-r--r--sca-cpp/trunk/modules/server/client-test.cpp79
-rw-r--r--sca-cpp/trunk/modules/server/client-test.scm (renamed from sca-cpp/trunk/modules/server/httpd-client.scm)0
-rw-r--r--sca-cpp/trunk/modules/server/domain-test.composite (renamed from sca-cpp/trunk/modules/server/httpd-test.composite)19
-rwxr-xr-xsca-cpp/trunk/modules/server/httpd-test6
-rw-r--r--sca-cpp/trunk/modules/server/impl-test.cpp76
-rw-r--r--sca-cpp/trunk/modules/server/mod-cpp.hpp20
-rw-r--r--sca-cpp/trunk/modules/server/mod-eval.cpp104
-rw-r--r--sca-cpp/trunk/modules/server/mod-scm.hpp30
-rwxr-xr-xsca-cpp/trunk/modules/server/server-test (renamed from sca-cpp/trunk/modules/server/http-test)15
-rw-r--r--sca-cpp/trunk/modules/server/server-test.scm (renamed from sca-cpp/trunk/modules/server/httpd-test.scm)0
-rwxr-xr-xsca-cpp/trunk/modules/server/wiring-test14
17 files changed, 409 insertions, 235 deletions
diff --git a/sca-cpp/trunk/modules/atom/atom.hpp b/sca-cpp/trunk/modules/atom/atom.hpp
index ac19b93e38..22489fd1d1 100644
--- a/sca-cpp/trunk/modules/atom/atom.hpp
+++ b/sca-cpp/trunk/modules/atom/atom.hpp
@@ -38,7 +38,7 @@ namespace atom {
/**
* Convert a list of elements to a list of values representing an ATOM entry.
*/
-const list<value> entryValue(const list<value>& e) {
+const list<value> entryValues(const list<value>& e) {
const list<value> lt = filter<value>(selector(mklist<value>(element, "title")), e);
const value t = isNil(lt)? value(std::string("")) : elementValue(car(lt));
const list<value> li = filter<value>(selector(mklist<value>(element, "id")), e);
@@ -53,7 +53,7 @@ const list<value> entryValue(const list<value>& e) {
const list<value> entriesValues(const list<value>& e) {
if (isNil(e))
return e;
- return cons<value>(entryValue(car(e)), entriesValues(cdr(e)));
+ return cons<value>(entryValues(car(e)), entriesValues(cdr(e)));
}
/**
@@ -63,7 +63,15 @@ const failable<list<value>, std::string> readEntry(const list<std::string>& ilis
const list<value> e = readXML(ilist);
if (isNil(e))
return mkfailure<list<value>, std::string>("Empty entry");
- return entryValue(car(e));
+ return entryValues(car(e));
+}
+
+/**
+ * Convert a list of values representing an ATOM entry to a value.
+ */
+const value entryValue(const list<value>& e) {
+ const list<value> v = elementsToValues(mklist<value>(caddr(e)));
+ return cons(car(e), mklist<value>(cadr(e), cdr<value>(car(v))));
}
/**
diff --git a/sca-cpp/trunk/modules/http/curl-test.cpp b/sca-cpp/trunk/modules/http/curl-test.cpp
index 0a6fbcd8a6..59944546a1 100644
--- a/sca-cpp/trunk/modules/http/curl-test.cpp
+++ b/sca-cpp/trunk/modules/http/curl-test.cpp
@@ -50,7 +50,7 @@ std::ostringstream* curlWriter(const std::string& s, std::ostringstream* os) {
}
const bool testGet() {
- CURLHandle ch;
+ CURLSession ch;
{
std::ostringstream os;
const failable<list<std::ostringstream*>, std::string> r = get<std::ostringstream*>(curlWriter, &os, "http://localhost:8090", ch);
@@ -66,7 +66,7 @@ const bool testGet() {
return true;
}
-const bool testGetLoop(const int count, CURLHandle& ch) {
+const bool testGetLoop(const int count, CURLSession& ch) {
if (count == 0)
return true;
const failable<value, std::string> r = get("http://localhost:8090", ch);
@@ -77,7 +77,7 @@ const bool testGetLoop(const int count, CURLHandle& ch) {
const bool testGetPerf() {
const int count = 50;
- CURLHandle ch;
+ CURLSession ch;
struct timeval start;
struct timeval end;
{
diff --git a/sca-cpp/trunk/modules/http/curl.hpp b/sca-cpp/trunk/modules/http/curl.hpp
index 6c3a3a47dc..fd2e9857d1 100644
--- a/sca-cpp/trunk/modules/http/curl.hpp
+++ b/sca-cpp/trunk/modules/http/curl.hpp
@@ -30,6 +30,7 @@
#include <curl/types.h>
#include <curl/easy.h>
#include <string>
+#include "gc.hpp"
#include "list.hpp"
#include "value.hpp"
#include "element.hpp"
@@ -41,11 +42,6 @@ namespace tuscany {
namespace http {
/**
- * Set to true to log HTTP content.
- */
-bool logContent = false;
-
-/**
* CURL library context, one per process.
*/
class CURLContext {
@@ -63,22 +59,45 @@ CURLContext curlContext;
/**
* Represents a CURL session handle.
*/
-class CURLHandle {
+class CURLSession {
public:
- CURLHandle() : h(curl_easy_init()) {
+ CURLSession() : ch(new CURLHandle()) {
}
- ~CURLHandle() {
- curl_easy_cleanup(h);
+
+ ~CURLSession() {
}
- operator CURL*() const {
- return h;
+ CURLSession(const CURLSession& c) : ch(c.ch) {
}
+
private:
- CURL* h;
+ class CURLHandle {
+ public:
+ CURLHandle() : h(curl_easy_init()) {
+ }
+ ~CURLHandle() {
+ curl_easy_cleanup(h);
+ h = NULL;
+ }
+ private:
+ CURL* h;
+
+ friend CURL* handle(const CURLSession& c);
+ };
+
+ const gc_ptr<CURLHandle> ch;
+
+ friend CURL* handle(const CURLSession& c);
};
/**
+ * Returns the CURL handle used by a CURL session.
+ */
+CURL* handle(const CURLSession& c) {
+ return c.ch->h;
+}
+
+/**
* Context passed to the read callback function.
*/
class CURLReadContext {
@@ -143,9 +162,10 @@ curl_slist* headers(curl_slist* cl, const list<std::string>& h) {
return headers(curl_slist_append(cl, std::string(car(h)).c_str()), cdr(h));
}
-template<typename R> const failable<list<R>, std::string> apply(const list<list<std::string> >& req, const lambda<R(std::string, R)>& reduce, const R& initial, const std::string& url, const std::string& verb, const CURLHandle& ch) {
+template<typename R> const failable<list<R>, std::string> apply(const list<list<std::string> >& req, const lambda<R(std::string, R)>& reduce, const R& initial, const std::string& url, const std::string& verb, const CURLSession& cs) {
// Init the curl session
+ CURL* ch = handle(cs);
curl_easy_reset(ch);
curl_easy_setopt(ch, CURLOPT_USERAGENT, "libcurl/1.0");
@@ -204,7 +224,9 @@ template<typename R> const failable<list<R>, std::string> apply(const list<list<
/**
* Evaluate an expression remotely, at the given URL.
*/
-const failable<value, std::string> evalExpr(const value& expr, const std::string& url, const CURLHandle& ch) {
+const failable<value, std::string> evalExpr(const value& expr, const std::string& url, const CURLSession& ch) {
+ debug(url, "http::evalExpr::url");
+ debug(expr, "http::evalExpr::input");
// Convert expression to a JSON-RPC request
json::JSONContext cx;
@@ -212,13 +234,6 @@ const failable<value, std::string> evalExpr(const value& expr, const std::string
if (!hasContent(jsreq))
return mkfailure<value, std::string>(reason(jsreq));
- if (logContent) {
- std::cout<< "content: " << std::endl;
- write(content(jsreq), std::cout);
- std::cout<< std::endl;
- std::cout.flush();
- }
-
// POST it to the URL
const list<std::string> h = mklist<std::string>("Content-Type: application/json-rpc");
const failable<list<list<std::string> >, std::string> res = apply<list<std::string> >(mklist<list<std::string> >(h, content(jsreq)), rcons<std::string>, list<std::string>(), url, "POST", ch);
@@ -226,19 +241,58 @@ const failable<value, std::string> evalExpr(const value& expr, const std::string
return mkfailure<value, std::string>(reason(res));
// Return result
- if (logContent) {
- std::cout << "content:" << std::endl;
- write(cadr<list<std::string> >(content(res)), std::cout);
- std::cout << std::endl;
- }
- const list<value> val = elementsToValues(content(json::readJSON(cadr<list<std::string> >(content(res)), cx)));
- return cadr<value>(cadr<value>(val));
+ failable<list<value>, std::string> jsres = json::readJSON(cadr<list<std::string> >(content(res)), cx);
+ if (!hasContent(jsres))
+ return mkfailure<value, std::string>(reason(jsres));
+ const list<value> val = elementsToValues(content(jsres));
+
+ const value rval(cadr<value>(cadr<value>(val)));
+ debug(rval, "http::evalExpr::result");
+ return rval;
+}
+
+/**
+ * Find and return a header.
+ */
+const failable<std::string, std::string> header(const std::string& prefix, const list<std::string>& h) {
+ if (isNil(h))
+ return mkfailure<std::string, std::string>(std::string("Couldn't find header: ") + prefix);
+ const std::string s = car(h);
+ if (s.find(prefix) != 0)
+ return header(prefix, cdr(h));
+ const std::string l(s.substr(prefix.length()));
+ return l.substr(0, l.find_first_of("\r\n"));
+}
+
+/**
+ * Find and return a location header.
+ */
+const failable<std::string, std::string> location(const list<std::string>& h) {
+ return header("Location: ", h);
+}
+
+/**
+ * Convert a location to an entry id.
+ */
+const failable<value, std::string> entryId(const failable<std::string, std::string> l) {
+ if (!hasContent(l))
+ return mkfailure<value, std::string>(reason(l));
+ const std::string ls(content(l));
+ return value(ls.substr(ls.find_last_of("/") + 1));
+}
+
+/**
+ * Find and return a content-type header.
+ */
+const failable<std::string, std::string> contentType(const list<std::string>& h) {
+ return header("Content-Type: ", h);
}
/**
* HTTP GET, return the resource at the given URL.
*/
-template<typename R> const failable<list<R>, std::string> get(const lambda<R(std::string, R)>& reduce, const R& initial, const std::string& url, const CURLHandle& ch) {
+template<typename R> const failable<list<R>, std::string> get(const lambda<R(std::string, R)>& reduce, const R& initial, const std::string& url, const CURLSession& ch) {
+ debug(url, "http::get::url");
const list<list<std::string> > req = mklist(list<std::string>(), list<std::string>());
return apply(req, reduce, initial, url, "GET", ch);
}
@@ -246,38 +300,41 @@ template<typename R> const failable<list<R>, std::string> get(const lambda<R(std
/**
* HTTP GET, return a list of values representing the resource at the given URL.
*/
-const failable<value, std::string> get(const std::string& url, const CURLHandle& ch) {
+const failable<value, std::string> get(const std::string& url, const CURLSession& ch) {
+ debug(url, "http::get::url");
// Get the contents of the resource at the given URL
const failable<list<list<std::string> >, std::string> res = get<list<std::string> >(rcons<std::string>, list<std::string>(), url, ch);
if (!hasContent(res))
return mkfailure<value, std::string>(reason(res));
+ const list<std::string> ls(reverse(cadr(content(res))));
- const std::string ct;
- if (ct.find("application/atom+xml") != std::string::npos) {
- // TODO Return an ATOM feed
+ const std::string ct(content(contentType(car(content(res)))));
+ if (ct == "application/atom+xml;type=entry") {
+ const value val(atom::entryValue(content(atom::readEntry(ls))));
+ debug(val, "http::get::result");
+ return val;
}
// Return the content as a string value
std::ostringstream os;
- write(reverse(cadr(content(res))), os);
- return value(os.str());
+ write(ls, os);
+ const value val(os.str());
+ debug(val, "http::get::result");
+ return val;
}
/**
* HTTP POST.
*/
-const failable<value, std::string> post(const value& val, const std::string& url, const CURLHandle& ch) {
+const failable<value, std::string> post(const value& val, const std::string& url, const CURLSession& ch) {
// Convert value to an ATOM entry
const failable<list<std::string>, std::string> entry = atom::writeATOMEntry(atom::entryValuesToElements(val));
if (!hasContent(entry))
return mkfailure<value, std::string>(reason(entry));
- if (logContent) {
- std::cout << "content:" << std::endl;
- write(list<std::string>(content(entry)), std::cout);
- std::cout << std::endl;
- }
+ debug(url, "http::post::url");
+ debug(content(entry), "http::post::input");
// POST it to the URL
const list<std::string> h = mklist<std::string>("Content-Type: application/atom+xml");
@@ -285,23 +342,24 @@ const failable<value, std::string> post(const value& val, const std::string& url
const failable<list<list<std::string> >, std::string> res = apply<list<std::string> >(req, rcons<std::string>, list<std::string>(), url, "POST", ch);
if (!hasContent(res))
return mkfailure<value, std::string>(reason(res));
- return value(true);
+
+ // Return the new entry id from the HTTP location header
+ const failable<value, std::string> eid(entryId(location(car(content(res)))));
+ debug(eid, "http::post::result");
+ return eid;
}
/**
* HTTP PUT.
*/
-const failable<value, std::string> put(const value& val, const std::string& url, const CURLHandle& ch) {
+const failable<value, std::string> put(const value& val, const std::string& url, const CURLSession& ch) {
// Convert value to an ATOM entry
const failable<list<std::string>, std::string> entry = atom::writeATOMEntry(atom::entryValuesToElements(val));
if (!hasContent(entry))
return mkfailure<value, std::string>(reason(entry));
- if (logContent) {
- std::cout << "content:" << std::endl;
- write(list<std::string>(content(entry)), std::cout);
- std::cout << std::endl;
- }
+ debug(url, "http::put::url");
+ debug(content(entry), "http::put::input");
// PUT it to the URL
const list<std::string> h = mklist<std::string>("Content-Type: application/atom+xml");
@@ -309,17 +367,23 @@ const failable<value, std::string> put(const value& val, const std::string& url,
const failable<list<list<std::string> >, std::string> res = apply<list<std::string> >(req, rcons<std::string>, list<std::string>(), url, "PUT", ch);
if (!hasContent(res))
return mkfailure<value, std::string>(reason(res));
+
+ debug(true, "http::put::result");
return value(true);
}
/**
* HTTP DELETE.
*/
-const failable<value, std::string> del(const std::string& url, const CURLHandle& ch) {
+const failable<value, std::string> del(const std::string& url, const CURLSession& ch) {
+ debug(url, "http::delete::url");
+
const list<list<std::string> > req = mklist(list<std::string>(), list<std::string>());
const failable<list<list<std::string> >, std::string> res = apply<list<std::string> >(req, rcons<std::string>, list<std::string>(), url, "DELETE", ch);
if (!hasContent(res))
return mkfailure<value, std::string>(reason(res));
+
+ debug(true, "http::delete::result");
return value(true);
}
@@ -327,7 +391,7 @@ const failable<value, std::string> del(const std::string& url, const CURLHandle&
* HTTP client proxy function.
*/
struct proxy {
- proxy(const std::string& url, const CURLHandle& ch) : url(url), ch(ch) {
+ proxy(const std::string& url, const CURLSession& ch) : url(url), ch(ch) {
}
const value operator()(const list<value>& args) const {
@@ -338,7 +402,7 @@ struct proxy {
}
const std::string url;
- const CURLHandle& ch;
+ const CURLSession ch;
};
}
diff --git a/sca-cpp/trunk/modules/http/http-test b/sca-cpp/trunk/modules/http/http-test
index 1ab0da64b9..0aaaec48df 100755
--- a/sca-cpp/trunk/modules/http/http-test
+++ b/sca-cpp/trunk/modules/http/http-test
@@ -28,5 +28,5 @@ rc=$?
# Cleanup
apachectl -k stop -d `pwd`/tmp
-sleep 2
+sleep 1
return $rc
diff --git a/sca-cpp/trunk/modules/http/httpd-test b/sca-cpp/trunk/modules/http/httpd-test
index 57c35c5cc9..8e1d681d84 100755
--- a/sca-cpp/trunk/modules/http/httpd-test
+++ b/sca-cpp/trunk/modules/http/httpd-test
@@ -31,7 +31,7 @@ rc=$?
# Cleanup
apachectl -k stop -d `pwd`/tmp
-sleep 2
+sleep 1
if [ "$rc" = "0" ]; then
echo "OK"
fi
diff --git a/sca-cpp/trunk/modules/http/httpd.hpp b/sca-cpp/trunk/modules/http/httpd.hpp
index a9ced05208..05b959f1d2 100644
--- a/sca-cpp/trunk/modules/http/httpd.hpp
+++ b/sca-cpp/trunk/modules/http/httpd.hpp
@@ -50,18 +50,13 @@
#include "list.hpp"
#include "value.hpp"
+#include "debug.hpp"
namespace tuscany {
namespace httpd {
/**
- * Set to true to log requests and content.
- */
-bool logRequests = false;
-bool logContent = false;
-
-/**
* Returns a server-scoped module configuration.
*/
template<typename C> void* makeServerConf(apr_pool_t *p, server_rec *s) {
@@ -120,7 +115,7 @@ const std::string path(const list<value>& p) {
*/
const char* optional(const char* s) {
if (s == NULL)
- return "(null)";
+ return "";
return s;
}
@@ -128,59 +123,40 @@ const std::string contentType(const request_rec* r) {
return optional(apr_table_get(r->headers_in, "Content-Type"));
}
+#ifdef _DEBUG
+
/**
- * Log HTTP request info.
+ * Debug log.
*/
-int logHeader(void* r, const char* key, const char* value) {
- std::cout << "header key: " << key << ", value: " << value << std::endl;
+int debugHeader(unused void* r, const char* key, const char* value) {
+ std::cerr << " header key: " << key << ", value: " << value << std::endl;
return 1;
}
-const bool logRequest(request_rec* r, const std::string& msg) {
- if (!logRequests)
- return true;
- std::cout << msg << std::endl;
- std::cout << "protocol: " << optional(r->protocol) << std::endl;
- std::cout << "method: " << optional(r->method) << std::endl;
- std::cout << "method number: " << r->method_number << std::endl;
- std::cout << "content type: " << contentType(r) << std::endl;
- std::cout << "content encoding: " << optional(r->content_encoding) << std::endl;
- apr_table_do(logHeader, r, r->headers_in, NULL);
- std::cout << "uri: " << optional(r->unparsed_uri) << std::endl;
- std::cout << "path: " << optional(r->uri) << std::endl;
- std::cout << "path info: " << optional(r->path_info) << std::endl;
- std::cout << "filename: " << optional(r->filename) << std::endl;
- std::cout << "path tokens: " << pathTokens(r->uri) << std::endl;
- std::cout << "args: " << optional(r->args) << std::endl;
- std::cout.flush();
+const bool debugRequest(request_rec* r, const std::string& msg) {
+ std::cerr << msg << ":" << std::endl;
+ std::cerr << " protocol: " << optional(r->protocol) << std::endl;
+ std::cerr << " method: " << optional(r->method) << std::endl;
+ std::cerr << " method number: " << r->method_number << std::endl;
+ std::cerr << " content type: " << contentType(r) << std::endl;
+ std::cerr << " content encoding: " << optional(r->content_encoding) << std::endl;
+ apr_table_do(debugHeader, r, r->headers_in, NULL);
+ std::cerr << " uri: " << optional(r->unparsed_uri) << std::endl;
+ std::cerr << " path: " << optional(r->uri) << std::endl;
+ std::cerr << " path info: " << optional(r->path_info) << std::endl;
+ std::cerr << " filename: " << optional(r->filename) << std::endl;
+ std::cerr << " path tokens: " << pathTokens(r->uri) << std::endl;
+ std::cerr << " args: " << optional(r->args) << std::endl;
return true;
}
-const bool logValue(const value& v, const std::string& msg) {
- if (!logContent)
- return true;
- std::cout<< msg << ": " << v << std::endl;
- std::cout.flush();
- return true;
-}
+#define httpdDebugRequest(r, msg) httpd::debugRequest(r, msg)
-const bool logValue(const failable<value, std::string>& v, const std::string& msg) {
- if (!logContent)
- return true;
- std::cout<< msg << ": " << v << std::endl;
- std::cout.flush();
- return true;
-}
+#else
-const bool logStrings(const list<std::string>& ls, const std::string& msg) {
- if (!logContent)
- return true;
- std::cout<< msg << ": " << std::endl;
- write(ls, std::cout);
- std::cout<< std::endl;
- std::cout.flush();
- return true;
-}
+#define httpdDebugRequest(r, msg)
+
+#endif
/**
* Returns a list of key value pairs from the args in a query string.
@@ -256,14 +232,6 @@ const char* url(const value& v, request_rec* r) {
}
/**
- * Convert an ATOM entry to a value.
- */
-const value feedEntry(const list<value>& e) {
- const list<value> v = elementsToValues(mklist<value>(caddr(e)));
- return cons(car(e), mklist<value>(cadr(e), cdr<value>(car(v))));
-}
-
-/**
* Write an HTTP result.
*/
const failable<int, std::string> writeResult(const failable<list<std::string>, std::string>& ls, const std::string& ct, request_rec* r) {
@@ -271,10 +239,7 @@ const failable<int, std::string> writeResult(const failable<list<std::string>, s
return mkfailure<int, std::string>(reason(ls));
std::ostringstream os;
write(content(ls), os);
- if (logContent) {
- std::cout<< "content: " << std::endl << os.str() << std::endl;
- std::cout.flush();
- }
+ debug(os.str(), "httpd::result");
const std::string etag(ap_md5(r->pool, (const unsigned char*)std::string(os.str()).c_str()));
const char* match = apr_table_get(r->headers_in, "If-None-Match");
@@ -283,7 +248,7 @@ const failable<int, std::string> writeResult(const failable<list<std::string>, s
r->status = HTTP_NOT_MODIFIED;
return OK;
}
- ap_set_content_type(r, ct.c_str());
+ ap_set_content_type(r, apr_pstrdup(r->pool, ct.c_str()));
ap_rputs(std::string(os.str()).c_str(), r);
return OK;
}
diff --git a/sca-cpp/trunk/modules/server/client-test.cpp b/sca-cpp/trunk/modules/server/client-test.cpp
index b43cb92c52..5888c481e3 100644
--- a/sca-cpp/trunk/modules/server/client-test.cpp
+++ b/sca-cpp/trunk/modules/server/client-test.cpp
@@ -50,7 +50,7 @@ std::ostringstream* curlWriter(const std::string& s, std::ostringstream* os) {
}
const bool testGet() {
- http::CURLHandle ch;
+ http::CURLSession ch;
{
std::ostringstream os;
const failable<list<std::ostringstream*>, std::string> r = http::get<std::ostringstream*>(curlWriter, &os, "http://localhost:8090", ch);
@@ -66,7 +66,7 @@ const bool testGet() {
return true;
}
-const bool testGetLoop(const int count, http::CURLHandle& ch) {
+const bool testGetLoop(const int count, http::CURLSession& ch) {
if (count == 0)
return true;
const failable<value, std::string> r = get("http://localhost:8090", ch);
@@ -77,16 +77,13 @@ const bool testGetLoop(const int count, http::CURLHandle& ch) {
const bool testGetPerf() {
const int count = 50;
- http::CURLHandle ch;
+ http::CURLSession ch;
struct timeval start;
struct timeval end;
{
testGetLoop(5, ch);
-
gettimeofday(&start, NULL);
-
testGetLoop(count, ch);
-
gettimeofday(&end, NULL);
std::cout << "Static GET test " << duration(start, end, count) << " ms" << std::endl;
}
@@ -94,13 +91,13 @@ const bool testGetPerf() {
}
const bool testEval() {
- http::CURLHandle ch;
+ http::CURLSession ch;
const value val = content(http::evalExpr(mklist<value>(std::string("echo"), std::string("Hello")), "http://localhost:8090/test", ch));
assert(val == std::string("Hello"));
return true;
}
-const bool testEvalLoop(const int count, http::CURLHandle& ch) {
+const bool testEvalLoop(const int count, http::CURLSession& ch) {
if (count == 0)
return true;
const value val = content(http::evalExpr(mklist<value>(std::string("echo"), std::string("Hello")), "http://localhost:8090/test", ch));
@@ -111,7 +108,7 @@ const bool testEvalLoop(const int count, http::CURLHandle& ch) {
const value blob(std::string(3000, 'A'));
const list<value> blobs = mklist(blob, blob, blob, blob, blob);
-const bool testBlobEvalLoop(const int count, http::CURLHandle& ch) {
+const bool testBlobEvalLoop(const int count, http::CURLSession& ch) {
if (count == 0)
return true;
const value val = content(http::evalExpr(mklist<value>(std::string("echo"), blobs), "http://localhost:8090/test", ch));
@@ -121,26 +118,20 @@ const bool testBlobEvalLoop(const int count, http::CURLHandle& ch) {
const bool testEvalPerf() {
const int count = 50;
- http::CURLHandle ch;
+ http::CURLSession ch;
struct timeval start;
struct timeval end;
{
testEvalLoop(5, ch);
-
gettimeofday(&start, NULL);
-
testEvalLoop(count, ch);
-
gettimeofday(&end, NULL);
std::cout << "JSON-RPC eval echo test " << duration(start, end, count) << " ms" << std::endl;
}
{
testBlobEvalLoop(5, ch);
-
gettimeofday(&start, NULL);
-
testBlobEvalLoop(count, ch);
-
gettimeofday(&end, NULL);
std::cout << "JSON-RPC eval blob test " << duration(start, end, count) << " ms" << std::endl;
}
@@ -156,23 +147,23 @@ bool testPost() {
<< (list<value>() << "name" << std::string("Apple"))
<< (list<value>() << "price" << std::string("$2.99"));
const list<value> a = mklist<value>(std::string("item"), std::string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i);
- http::CURLHandle ch;
- value rc = content(http::post(a, "http://localhost:8090/test", ch));
- assert(rc == value(true));
+ http::CURLSession ch;
+ const failable<value, std::string> id = http::post(a, "http://localhost:8090/test", ch);
+ assert(hasContent(id));
return true;
}
-const bool testPostLoop(const int count, const value& val, http::CURLHandle& ch) {
+const bool testPostLoop(const int count, const value& val, http::CURLSession& ch) {
if (count == 0)
return true;
- const value rc = content(http::post(val, "http://localhost:8090/test", ch));
- assert(rc == value(true));
+ const failable<value, std::string> id = http::post(val, "http://localhost:8090/test", ch);
+ assert(hasContent(id));
return testPostLoop(count - 1, val, ch);
}
const bool testPostPerf() {
const int count = 50;
- http::CURLHandle ch;
+ http::CURLSession ch;
struct timeval start;
struct timeval end;
{
@@ -181,11 +172,8 @@ const bool testPostPerf() {
<< (list<value>() << "price" << std::string("$2.99"));
const list<value> val = mklist<value>(std::string("item"), std::string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i);
testPostLoop(5, val, ch);
-
gettimeofday(&start, NULL);
-
testPostLoop(count, val, ch);
-
gettimeofday(&end, NULL);
std::cout << "ATOMPub POST small test " << duration(start, end, count) << " ms" << std::endl;
}
@@ -200,11 +188,8 @@ const bool testPostPerf() {
<< (list<value>() << "price" << std::string("$2.99"));
const list<value> val = mklist<value>(std::string("item"), std::string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i);
testPostLoop(5, val, ch);
-
gettimeofday(&start, NULL);
-
testPostLoop(count, val, ch);
-
gettimeofday(&end, NULL);
std::cout << "ATOMPub POST blob test " << duration(start, end, count) << " ms" << std::endl;
}
@@ -216,19 +201,49 @@ const bool testPut() {
<< (list<value>() << "name" << std::string("Apple"))
<< (list<value>() << "price" << std::string("$2.99"));
const list<value> a = mklist<value>(std::string("item"), std::string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i);
- http::CURLHandle ch;
+ http::CURLSession ch;
value rc = content(http::put(a, "http://localhost:8090/test/111", ch));
assert(rc == value(true));
return true;
}
const bool testDel() {
- http::CURLHandle ch;
+ http::CURLSession ch;
value rc = content(http::del("http://localhost:8090/test/123456789", ch));
assert(rc == value(true));
return true;
}
+const bool testEvalCpp() {
+ http::CURLSession ch;
+ const value val = content(http::evalExpr(mklist<value>(std::string("hello"), std::string("world")), "http://localhost:8090/cpp", ch));
+ assert(val == std::string("hello world"));
+ return true;
+}
+
+const bool testEvalCppLoop(const int count, http::CURLSession& ch) {
+ if (count == 0)
+ return true;
+ const value val = content(http::evalExpr(mklist<value>(std::string("hello"), std::string("world")), "http://localhost:8090/cpp", ch));
+ assert(val == std::string("hello world"));
+ return testEvalCppLoop(count - 1, ch);
+}
+
+const bool testEvalCppPerf() {
+ const int count = 50;
+ http::CURLSession ch;
+ struct timeval start;
+ struct timeval end;
+ {
+ testEvalCppLoop(5, ch);
+ gettimeofday(&start, NULL);
+ testEvalCppLoop(count, ch);
+ gettimeofday(&end, NULL);
+ std::cout << "JSON-RPC C++ eval test " << duration(start, end, count) << " ms" << std::endl;
+ }
+ return true;
+}
+
}
}
@@ -244,6 +259,8 @@ int main() {
tuscany::server::testFeed();
tuscany::server::testPut();
tuscany::server::testDel();
+ tuscany::server::testEvalCpp();
+ tuscany::server::testEvalCppPerf();
std::cout << "OK" << std::endl;
diff --git a/sca-cpp/trunk/modules/server/httpd-client.scm b/sca-cpp/trunk/modules/server/client-test.scm
index 12275693f4..12275693f4 100644
--- a/sca-cpp/trunk/modules/server/httpd-client.scm
+++ b/sca-cpp/trunk/modules/server/client-test.scm
diff --git a/sca-cpp/trunk/modules/server/httpd-test.composite b/sca-cpp/trunk/modules/server/domain-test.composite
index 875d26ae1b..48570e64d3 100644
--- a/sca-cpp/trunk/modules/server/httpd-test.composite
+++ b/sca-cpp/trunk/modules/server/domain-test.composite
@@ -19,18 +19,25 @@
-->
<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200903"
xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
- targetNamespace="http://test"
- name="httpd-test">
+ targetNamespace="http://domain/test"
+ name="domain-test">
- <component name="httpd-test">
- <t:implementation.scheme uri="httpd-test.scm"/>
+ <component name="server-test">
+ <t:implementation.scheme uri="server-test.scm"/>
<service name="test">
<t:binding.http uri="test"/>
</service>
</component>
- <component name="httpd-client">
- <t:implementation.scheme uri="httpd-client.scm"/>
+ <component name="cpp-test">
+ <t:implementation.cpp uri=".libs/libimpl-test"/>
+ <service name="cpp">
+ <t:binding.http uri="cpp"/>
+ </service>
+ </component>
+
+ <component name="client-test">
+ <t:implementation.scheme uri="client-test.scm"/>
<service name="client">
<t:binding.http uri="client"/>
</service>
diff --git a/sca-cpp/trunk/modules/server/httpd-test b/sca-cpp/trunk/modules/server/httpd-test
index 7fa2112f75..2f50c9f3c3 100755
--- a/sca-cpp/trunk/modules/server/httpd-test
+++ b/sca-cpp/trunk/modules/server/httpd-test
@@ -27,8 +27,8 @@ cat >>tmp/conf/httpd.conf <<EOF
<Location /test>
SetHandler mod_tuscany_eval
SCAContribution `pwd`/
-SCAComposite httpd-test.composite
-SCAComponent httpd-test
+SCAComposite domain-test.composite
+SCAComponent server-test
</Location>
EOF
@@ -73,7 +73,7 @@ fi
# Cleanup
apachectl -k stop -d `pwd`/tmp
-sleep 2
+sleep 1
if [ "$rc" = "0" ]; then
echo "OK"
fi
diff --git a/sca-cpp/trunk/modules/server/impl-test.cpp b/sca-cpp/trunk/modules/server/impl-test.cpp
new file mode 100644
index 0000000000..217c6f5171
--- /dev/null
+++ b/sca-cpp/trunk/modules/server/impl-test.cpp
@@ -0,0 +1,76 @@
+/*
+ * 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 component implementation.
+ */
+
+#include <string>
+
+#include "function.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "debug.hpp"
+
+namespace tuscany {
+namespace server {
+
+const failable<value, std::string> get(unused const list<value>& params) {
+ return value(std::string("Hey"));
+}
+
+const failable<value, std::string> post(unused const list<value>& params) {
+ return value(std::string("1234"));
+}
+
+const failable<value, std::string> put(unused const list<value>& params) {
+ return value(true);
+}
+
+const failable<value, std::string> del(unused const list<value>& params) {
+ return value(true);
+}
+
+const failable<value, std::string> hello(const list<value>& params) {
+ return value("hello " + std::string(car(params)));
+}
+
+}
+}
+
+extern "C" {
+
+const tuscany::failable<tuscany::value, std::string> eval(const tuscany::value& func, const tuscany::list<tuscany::value>& params) {
+ if (func == "get")
+ return tuscany::server::get(params);
+ if (func == "post")
+ return tuscany::server::post(params);
+ if (func == "put")
+ return tuscany::server::put(params);
+ if (func == "del")
+ return tuscany::server::del(params);
+ if (func == "hello")
+ return tuscany::server::hello(params);
+ return tuscany::mkfailure<tuscany::value, std::string>(std::string("Function not supported: ") + std::string(func));
+}
+
+}
diff --git a/sca-cpp/trunk/modules/server/mod-cpp.hpp b/sca-cpp/trunk/modules/server/mod-cpp.hpp
index cb24b76f6c..99b69a0d9f 100644
--- a/sca-cpp/trunk/modules/server/mod-cpp.hpp
+++ b/sca-cpp/trunk/modules/server/mod-cpp.hpp
@@ -34,6 +34,7 @@
#include "function.hpp"
#include "list.hpp"
#include "value.hpp"
+#include "debug.hpp"
#include "monad.hpp"
#include "dynlib.hpp"
#include "cache.hpp"
@@ -52,12 +53,13 @@ namespace cpp {
struct evalImplementation {
const lib ilib;
const ilambda impl;
- evalImplementation(const lib& ilib, const ilambda& impl) : ilib(ilib), impl(impl) {
+ const list<value> px;
+ evalImplementation(const lib& ilib, const ilambda& impl, const list<value>& px) : ilib(ilib), impl(impl), px(px) {
}
const failable<value, std::string> operator()(const value& func, const list<value>& params) const {
- httpd::logValue(cons<value>(func, params), "expr");
- const failable<value, std::string> val = impl(func, params);
- httpd::logValue(content(val), "val");
+ debug(cons<value>(func, params), "modeval::cpp::evalImplementation::input");
+ const failable<value, std::string> val = impl(func, append(params, px));
+ debug(content(val), "modeval::cpp::evalImplementation::result");
return val;
}
};
@@ -65,7 +67,7 @@ struct evalImplementation {
/**
* Read a C++ component implementation.
*/
-const failable<ilambda, std::string> readLatestImplementation(const std::string path) {
+const failable<ilambda, std::string> readLatestImplementation(const std::string path, const list<value>& px) {
const failable<lib, std::string> ilib(dynlib(path));
if (!hasContent(ilib))
return mkfailure<ilambda, std::string>(reason(ilib));
@@ -73,14 +75,14 @@ const failable<ilambda, std::string> readLatestImplementation(const std::string
const failable<ilambda, std::string> impl(dynlambda<failable<value, std::string>(value, list<value>)>("eval", content(ilib)));
if (!hasContent(impl))
return impl;
- return ilambda(evalImplementation(content(ilib), content(impl)));
+ return ilambda(evalImplementation(content(ilib), content(impl), px));
}
-const cached<failable<ilambda, std::string> > readImplementation(const std::string& path) {
- const lambda<failable<ilambda, std::string>(std::string)> ri(readLatestImplementation);
+const cached<failable<ilambda, std::string> > readImplementation(const std::string& path, const list<value>& px) {
+ const lambda<failable<ilambda, std::string>(std::string, list<value>)> ri(readLatestImplementation);
const lambda<unsigned long(std::string)> ft(latestFileTime);
const std::string p(path + dynlibExt);
- return cached<failable<ilambda, std::string> >(curry(ri, p), curry(ft, p));
+ return cached<failable<ilambda, std::string> >(curry(ri, p, px), curry(ft, p));
}
}
diff --git a/sca-cpp/trunk/modules/server/mod-eval.cpp b/sca-cpp/trunk/modules/server/mod-eval.cpp
index f843b9bdc5..aa0a6067a1 100644
--- a/sca-cpp/trunk/modules/server/mod-eval.cpp
+++ b/sca-cpp/trunk/modules/server/mod-eval.cpp
@@ -57,10 +57,11 @@ namespace modeval {
*/
class ServerConf {
public:
- ServerConf(server_rec* s) : s(s), home("") {
+ ServerConf(server_rec* s) : s(s), home(""), wiringHost("") {
}
- server_rec* s;
+ const server_rec* s;
std::string home;
+ std::string wiringHost;
};
/**
@@ -77,7 +78,7 @@ class DirConf {
public:
DirConf(char* dirspec) : dirspec(dirspec), contributionPath(""), compositeName(""), componentName(""), implementationPath("") {
}
- char* dirspec;
+ const char* dirspec;
std::string contributionPath;
std::string compositeName;
std::string componentName;
@@ -89,7 +90,8 @@ public:
/**
* Handle an HTTP GET.
*/
-const failable<int, std::string> get(request_rec* r, const ilambda& impl, const list<value>& px) {
+const failable<int, std::string> get(request_rec* r, const ilambda& impl) {
+ debug(r->uri, "modeval::get::url");
// Inspect the query string
const list<list<value> > args = httpd::queryArgs(r);
@@ -105,7 +107,7 @@ const failable<int, std::string> get(request_rec* r, const ilambda& impl, const
const list<value> params = httpd::queryParams(args);
// Apply the requested function
- const failable<value, std::string> val = impl(func, append(params, px));
+ const failable<value, std::string> val = impl(func, params);
if (!hasContent(val))
return mkfailure<int, std::string>(reason(val));
@@ -117,14 +119,14 @@ const failable<int, std::string> get(request_rec* r, const ilambda& impl, const
// Evaluate an ATOM GET request and return an ATOM feed
const list<value> id(httpd::path(r->path_info));
if (isNil(id)) {
- const failable<value, std::string> val = impl("getall", px);
+ const failable<value, std::string> val = impl("getall", list<value>());
if (!hasContent(val))
return mkfailure<int, std::string>(reason(val));
return httpd::writeResult(atom::writeATOMFeed(atom::feedValuesToElements(content(val))), "application/atom+xml;type=feed", r);
}
// Evaluate an ATOM GET and return an ATOM entry
- const failable<value, std::string> val = impl("get", cons<value>(car(id), px));
+ const failable<value, std::string> val = impl("get", mklist<value>(car(id)));
if (!hasContent(val))
return mkfailure<int, std::string>(reason(val));
return httpd::writeResult(atom::writeATOMEntry(atom::entryValuesToElements(content(val))), "application/atom+xml;type=entry", r);
@@ -133,9 +135,10 @@ const failable<int, std::string> get(request_rec* r, const ilambda& impl, const
/**
* Handle an HTTP POST.
*/
-const failable<int, std::string> post(request_rec* r, const ilambda& impl, const list<value>& px) {
+const failable<int, std::string> post(request_rec* r, const ilambda& impl) {
const list<std::string> ls = httpd::read(r);
- httpd::logStrings(ls, "content");
+ debug(r->uri, "modeval::post::url");
+ debug(ls, "modeval::post::input");
// Evaluate a JSON-RPC request and return a JSON result
const std::string ct = httpd::contentType(r);
@@ -150,7 +153,7 @@ const failable<int, std::string> post(request_rec* r, const ilambda& impl, const
const list<value> params = (list<value>)cadr(assoc(value("params"), args));
// Evaluate the request expression
- const failable<value, std::string> val = impl(func, append(params, px));
+ const failable<value, std::string> val = impl(func, params);
if (!hasContent(val))
return mkfailure<int, std::string>(reason(val));
@@ -162,8 +165,8 @@ const failable<int, std::string> post(request_rec* r, const ilambda& impl, const
if (ct.find("application/atom+xml") != std::string::npos) {
// Evaluate the request expression
- const value entry = httpd::feedEntry(content(atom::readEntry(ls)));
- const failable<value, std::string> val = impl("post", cons<value>(entry, px));
+ const value entry = atom::entryValue(content(atom::readEntry(ls)));
+ const failable<value, std::string> val = impl("post", mklist<value>(entry));
if (!hasContent(val))
return mkfailure<int, std::string>(reason(val));
@@ -179,14 +182,15 @@ const failable<int, std::string> post(request_rec* r, const ilambda& impl, const
/**
* Handle an HTTP PUT.
*/
-const failable<int, std::string> put(request_rec* r, const ilambda& impl, const list<value>& px) {
+const failable<int, std::string> put(request_rec* r, const ilambda& impl) {
const list<std::string> ls = httpd::read(r);
- httpd::logStrings(ls, "content");
+ debug(r->uri, "modeval::put::url");
+ debug(ls, "modeval::put::input");
// Evaluate an ATOM PUT request
const list<value> id(httpd::path(r->path_info));
- const value entry = httpd::feedEntry(content(atom::readEntry(ls)));
- const failable<value, std::string> val = impl("put", append(mklist<value>(entry, car(id)), px));
+ const value entry = atom::entryValue(content(atom::readEntry(ls)));
+ const failable<value, std::string> val = impl("put", mklist<value>(car(id), entry));
if (!hasContent(val))
return mkfailure<int, std::string>(reason(val));
if (val == value(false))
@@ -197,11 +201,12 @@ const failable<int, std::string> put(request_rec* r, const ilambda& impl, const
/**
* Handle an HTTP DELETE.
*/
-const failable<int, std::string> del(request_rec* r, const ilambda& impl, const list<value>& px) {
+const failable<int, std::string> del(request_rec* r, const ilambda& impl) {
+ debug(r->uri, "modeval::delete::url");
// Evaluate an ATOM delete request
const list<value> id(httpd::path(r->path_info));
- const failable<value, std::string> val = impl("delete", cons<value>(car(id), px));
+ const failable<value, std::string> val = impl("delete", mklist<value>(car(id)));
if (!hasContent(val))
return mkfailure<int, std::string>(reason(val));
if (val == value(false))
@@ -237,11 +242,11 @@ const cached<failable<value, std::string> > component(DirConf* conf) {
/**
* Convert a list of component references to a list of HTTP proxy lambdas.
*/
-const value mkproxy(const value& ref, const std::string& base, const http::CURLHandle& ch) {
- return eval::primitiveProcedure(http::proxy(base + std::string(scdl::name(ref)), ch));
+const value mkproxy(const value& ref, const std::string& base, const http::CURLSession& ch) {
+ return lambda<value(list<value>&)>(http::proxy(base + std::string(scdl::name(ref)), ch));
}
-const list<value> proxies(const list<value>& refs, const std::string& base, const http::CURLHandle& ch) {
+const list<value> proxies(const list<value>& refs, const std::string& base, const http::CURLSession& ch) {
if (isNil(refs))
return refs;
return cons(mkproxy(car(refs), base, ch), proxies(cdr(refs), base, ch));
@@ -251,11 +256,11 @@ const list<value> proxies(const list<value>& refs, const std::string& base, cons
* Returns the component implementation with the given implementation type and path.
* For now only Scheme and C++ implementations are supported.
*/
-const cached<failable<ilambda, std::string> > implementation(const std::string& itype, const std::string& path) {
+const cached<failable<ilambda, std::string> > implementation(const std::string& itype, const std::string& path, const list<value>& px) {
if (itype.find(".scheme") != std::string::npos)
- return latest(scm::readImplementation(path));
+ return latest(scm::readImplementation(path, px));
if (itype.find(".cpp") != std::string::npos)
- return latest(cpp::readImplementation(path));
+ return latest(cpp::readImplementation(path, px));
return cached<failable<ilambda, std::string> >();
}
@@ -265,7 +270,7 @@ const cached<failable<ilambda, std::string> > implementation(const std::string&
int handler(request_rec *r) {
if(strcmp(r->handler, "mod_tuscany_eval"))
return DECLINED;
- httpd::logRequest(r, "mod_tuscany_eval::handler");
+ httpdDebugRequest(r, "modeval::handler::input");
// Set up the read policy
const int rc = httpd::setupReadPolicy(r);
@@ -283,8 +288,19 @@ int handler(request_rec *r) {
const value ielement= scdl::implementation(content(comp));
const std::string path = conf.contributionPath + std::string(scdl::uri(ielement));
if (path != conf.implementationPath) {
+
+ // Convert component references to configured proxy lambdas
+ const ServerConf& sconf = httpd::serverConf<ServerConf>(r, &mod_tuscany_eval);
+ std::ostringstream base;
+ if (sconf.wiringHost == "")
+ base << "http://localhost:" << ap_get_server_port(r) << "/references/" << std::string(scdl::name(content(comp))) << "/";
+ else
+ base << "http://" << sconf.wiringHost << "/references/" << std::string(scdl::name(content(comp))) << "/";
+ http::CURLSession ch;
+ const list<value> px(proxies(scdl::references(content(comp)), base.str(), ch));
+
+ conf.implementation = implementation(elementName(ielement), path, px);
conf.implementationPath = path;
- conf.implementation = implementation(elementName(ielement), path);
}
else
conf.implementation = latest(conf.implementation);
@@ -292,47 +308,46 @@ int handler(request_rec *r) {
if (!hasContent(impl))
return HTTP_NOT_FOUND;
- // Convert component references to configured proxy lambdas
- std::ostringstream base;
- base << "http://localhost:" << (debugWiringPort == 0? ap_get_server_port(r) : debugWiringPort) << "/references/" << std::string(scdl::name(content(comp))) << "/";
- http::CURLHandle ch;
- const list<value> px(proxies(scdl::references(content(comp)), base.str(), ch));
-
// Handle HTTP method
if (r->header_only)
return OK;
if(r->method_number == M_GET)
- return httpd::reportStatus(get(r, content(impl), px));
+ return httpd::reportStatus(get(r, content(impl)));
if(r->method_number == M_POST)
- return httpd::reportStatus(post(r, content(impl), px));
+ return httpd::reportStatus(post(r, content(impl)));
if(r->method_number == M_PUT)
- return httpd::reportStatus(put(r, content(impl), px));
+ return httpd::reportStatus(put(r, content(impl)));
if(r->method_number == M_DELETE)
- return httpd::reportStatus(del(r, content(impl), px));
+ return httpd::reportStatus(del(r, content(impl)));
return HTTP_NOT_IMPLEMENTED;
}
/**
* Configuration commands.
*/
-const char *confHome(cmd_parms *cmd, void *dummy, const char *arg) {
+const char *confHome(cmd_parms *cmd, unused void *dummy, const char *arg) {
ServerConf *c = (ServerConf*)ap_get_module_config(cmd->server->module_config, &mod_tuscany_eval);
c->home = arg;
return NULL;
}
-const char *confContribution(cmd_parms *cmd, void *c, const char *arg) {
+const char *confWiringHost(cmd_parms *cmd, unused void *dummy, const char *arg) {
+ ServerConf *c = (ServerConf*)ap_get_module_config(cmd->server->module_config, &mod_tuscany_eval);
+ c->wiringHost = arg;
+ return NULL;
+}
+const char *confContribution(unused cmd_parms *cmd, void *c, const char *arg) {
DirConf* conf = (DirConf*)c;
conf->contributionPath = arg;
conf->component = component(conf);
return NULL;
}
-const char *confComposite(cmd_parms *cmd, void *c, const char *arg) {
+const char *confComposite(unused cmd_parms *cmd, void *c, const char *arg) {
DirConf* conf = (DirConf*)c;
conf->compositeName = arg;
conf->component = component(conf);
return NULL;
}
-const char *confComponent(cmd_parms *cmd, void *c, const char *arg) {
+const char *confComponent(unused cmd_parms *cmd, void *c, const char *arg) {
DirConf* conf = (DirConf*)c;
conf->componentName = arg;
conf->component = component(conf);
@@ -344,17 +359,18 @@ const char *confComponent(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("SCAWiringHost", (const char*(*)())confWiringHost, NULL, RSRC_CONF, "SCA wiring host"),
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("SCAComponent", (const char*(*)())confComponent, NULL, ACCESS_CONF, "SCA component name"),
- {NULL}
+ {NULL, NULL, NULL, 0, NO_ARGS, NULL}
};
-int postConfig(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) {
+int postConfig(unused apr_pool_t *p, unused apr_pool_t *plog, unused apr_pool_t *ptemp, unused server_rec *s) {
return OK;
}
-void childInit(apr_pool_t* p, server_rec* svr_rec) {
+void childInit(unused apr_pool_t* p, server_rec* svr_rec) {
ServerConf *c = (ServerConf*)ap_get_module_config(svr_rec->module_config, &mod_tuscany_eval);
if(c == NULL) {
std::cerr << "[Tuscany] Due to one or more errors mod_tuscany_eval loading failed. Causing apache to stop loading." << std::endl;
@@ -362,7 +378,7 @@ void childInit(apr_pool_t* p, server_rec* svr_rec) {
}
}
-void registerHooks(apr_pool_t *p) {
+void registerHooks(unused apr_pool_t *p) {
ap_hook_post_config(postConfig, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_child_init(childInit, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_handler(handler, NULL, NULL, APR_HOOK_MIDDLE);
diff --git a/sca-cpp/trunk/modules/server/mod-scm.hpp b/sca-cpp/trunk/modules/server/mod-scm.hpp
index 386d032695..586b90190f 100644
--- a/sca-cpp/trunk/modules/server/mod-scm.hpp
+++ b/sca-cpp/trunk/modules/server/mod-scm.hpp
@@ -34,8 +34,10 @@
#include "function.hpp"
#include "list.hpp"
#include "value.hpp"
+#include "debug.hpp"
#include "monad.hpp"
#include "cache.hpp"
+#include "../eval/primitive.hpp"
#include "../eval/driver.hpp"
#include "../http/httpd.hpp"
#include "mod-eval.hpp"
@@ -46,19 +48,29 @@ namespace modeval {
namespace scm {
/**
+ * Convert proxy lambdas to evaluator primitive procedures.
+ */
+const list<value> primitiveProcedures(const list<value>& l) {
+ if (isNil(l))
+ return l;
+ return cons<value>(mklist<value>(eval::primitiveSymbol, car(l)), primitiveProcedures(cdr(l)));
+}
+
+/**
* Evaluate a script component implementation function.
*/
struct evalImplementation {
const value impl;
- evalImplementation(const value& impl) : impl(impl) {
+ const list<value> px;
+ evalImplementation(const value& impl, const list<value>& px) : impl(impl), px(eval::quotedParameters(primitiveProcedures(px))) {
}
const failable<value, std::string> operator()(const value& func, const list<value>& params) const {
- const value expr = cons<value>(func, eval::quotedParameters(params));
- httpd::logValue(expr, "expr");
+ const value expr = cons<value>(func, append(eval::quotedParameters(params), px));
+ debug(expr, "modeval::scm::evalImplementation::input");
gc_pool pool;
eval::Env globalEnv = eval::setupEnvironment(pool);
const value val = eval::evalScript(expr, impl, globalEnv, pool);
- httpd::logValue(val, "val");
+ debug(val, "modeval::scm::evalImplementation::result");
if (isNil(val))
return mkfailure<value, std::string>("Could not evaluate expression");
return val;
@@ -68,20 +80,20 @@ struct evalImplementation {
/**
* Read a script component implementation.
*/
-const failable<ilambda, std::string> readLatestImplementation(const std::string path) {
+const failable<ilambda, std::string> readLatestImplementation(const std::string path, const list<value>& px) {
std::ifstream is(path.c_str(), std::ios_base::in);
if (is.fail() || is.bad())
return mkfailure<ilambda, std::string>("Could not read implementation: " + path);
const value impl = eval::readScript(is);
if (isNil(impl))
return mkfailure<ilambda, std::string>("Could not read implementation: " + path);
- return ilambda(evalImplementation(impl));
+ return ilambda(evalImplementation(impl, px));
}
-const cached<failable<ilambda, std::string> > readImplementation(const std::string& path) {
- const lambda<failable<ilambda, std::string>(std::string)> ri(readLatestImplementation);
+const cached<failable<ilambda, std::string> > readImplementation(const std::string& path, const list<value>& px) {
+ const lambda<failable<ilambda, std::string>(std::string, list<value>)> ri(readLatestImplementation);
const lambda<unsigned long(std::string)> ft(latestFileTime);
- return cached<failable<ilambda, std::string> >(curry(ri, path), curry(ft, path));
+ return cached<failable<ilambda, std::string> >(curry(ri, path, px), curry(ft, path));
}
}
diff --git a/sca-cpp/trunk/modules/server/http-test b/sca-cpp/trunk/modules/server/server-test
index 6d23911c31..9c517f38b6 100755
--- a/sca-cpp/trunk/modules/server/http-test
+++ b/sca-cpp/trunk/modules/server/server-test
@@ -25,8 +25,15 @@ cat >>tmp/conf/httpd.conf <<EOF
<Location /test>
SetHandler mod_tuscany_eval
SCAContribution `pwd`/
-SCAComposite httpd-test.composite
-SCAComponent httpd-test
+SCAComposite domain-test.composite
+SCAComponent server-test
+</Location>
+
+<Location /cpp>
+SetHandler mod_tuscany_eval
+SCAContribution `pwd`/
+SCAComposite domain-test.composite
+SCAComponent cpp-test
</Location>
EOF
@@ -34,10 +41,10 @@ apachectl -k start -d `pwd`/tmp
sleep 1
# Test
-./client-test
+./client-test 2>/dev/null
rc=$?
# Cleanup
apachectl -k stop -d `pwd`/tmp
-sleep 2
+sleep 1
return $rc
diff --git a/sca-cpp/trunk/modules/server/httpd-test.scm b/sca-cpp/trunk/modules/server/server-test.scm
index 0566eaf36f..0566eaf36f 100644
--- a/sca-cpp/trunk/modules/server/httpd-test.scm
+++ b/sca-cpp/trunk/modules/server/server-test.scm
diff --git a/sca-cpp/trunk/modules/server/wiring-test b/sca-cpp/trunk/modules/server/wiring-test
index c50732ddb2..5f77d4c6f8 100755
--- a/sca-cpp/trunk/modules/server/wiring-test
+++ b/sca-cpp/trunk/modules/server/wiring-test
@@ -27,21 +27,21 @@ cat >>tmp/conf/httpd.conf <<EOF
<Location /test>
SetHandler mod_tuscany_eval
SCAContribution `pwd`/
-SCAComposite httpd-test.composite
-SCAComponent httpd-test
+SCAComposite domain-test.composite
+SCAComponent server-test
</Location>
<Location /client>
SetHandler mod_tuscany_eval
-SCAContribution /home/delfinoj/SCAZone/Source/tuscany-cpp/sca/modules/http/
-SCAComposite httpd-test.composite
-SCAComponent httpd-client
+SCAContribution `pwd`/
+SCAComposite domain-test.composite
+SCAComponent client-test
</Location>
<Location /references>
SetHandler mod_tuscany_wiring
SCAContribution `pwd`/
-SCAComposite httpd-test.composite
+SCAComposite domain-test.composite
</Location>
EOF
@@ -86,7 +86,7 @@ fi
# Cleanup
apachectl -k stop -d `pwd`/tmp
-sleep 2
+sleep 1
if [ "$rc" = "0" ]; then
echo "OK"
fi