diff options
author | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2013-02-20 21:13:02 (GMT) |
---|---|---|
committer | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2013-02-20 21:13:02 (GMT) |
commit | a56f28b0db56ff3e39f0b50e4c55c52b7aeec696 (patch) | |
tree | 41cf67ea5cee9593e86272ab55367653fbd1c2f3 /src/uscxml/plugins/invoker | |
parent | 7c779099b3acd1fa969dde718299484ebe0d2775 (diff) | |
download | uscxml-a56f28b0db56ff3e39f0b50e4c55c52b7aeec696.zip uscxml-a56f28b0db56ff3e39f0b50e4c55c52b7aeec696.tar.gz uscxml-a56f28b0db56ff3e39f0b50e4c55c52b7aeec696.tar.bz2 |
See detailled log
- Builds on windows again
- All HTTP requests are no passed into interpreter
- New response element to reply with data
- Moved basichttp URL
- New HTTP servlet invoker to register additional URLs
- More bugfixes than I care to mention
Diffstat (limited to 'src/uscxml/plugins/invoker')
5 files changed, 222 insertions, 20 deletions
diff --git a/src/uscxml/plugins/invoker/filesystem/dirmon/DirMonInvoker.cpp b/src/uscxml/plugins/invoker/filesystem/dirmon/DirMonInvoker.cpp index 8489d1d..2d308ce 100644 --- a/src/uscxml/plugins/invoker/filesystem/dirmon/DirMonInvoker.cpp +++ b/src/uscxml/plugins/invoker/filesystem/dirmon/DirMonInvoker.cpp @@ -116,13 +116,13 @@ void DirMonInvoker::handleFileAction(FW::WatchID watchid, const FW::String& dir, break; } - event.compound["file"].compound["name"] = Data(filename, Data::VERBATIM); - event.compound["file"].compound["dir"] = Data(dir, Data::VERBATIM); + event.data.compound["file"].compound["name"] = Data(filename, Data::VERBATIM); + event.data.compound["file"].compound["dir"] = Data(dir, Data::VERBATIM); - event.compound["file"].compound["mtime"] = toStr(fileStat.st_mtime); - event.compound["file"].compound["ctime"] = toStr(fileStat.st_ctime); - event.compound["file"].compound["atime"] = toStr(fileStat.st_atime); - event.compound["file"].compound["size"] = toStr(fileStat.st_size); + event.data.compound["file"].compound["mtime"] = toStr(fileStat.st_mtime); + event.data.compound["file"].compound["ctime"] = toStr(fileStat.st_ctime); + event.data.compound["file"].compound["atime"] = toStr(fileStat.st_atime); + event.data.compound["file"].compound["size"] = toStr(fileStat.st_size); returnEvent(event); } @@ -158,8 +158,8 @@ void DirMonInvoker::reportExistingIn(const std::string dir, FW::WatchID watchid) if (boost::iequals(dname, ".") || boost::iequals(dname, "..")) continue; - char* filename; - asprintf(&filename, "%s/%s", dir.c_str(), dname.c_str()); + char* filename = (char*)malloc(dir.size() + dname.size() + 2); + sprintf(filename, "%s/%s", dir.c_str(), dname.c_str()); struct stat fileStat; if (stat(filename, &fileStat) != 0) { diff --git a/src/uscxml/plugins/invoker/http/HTTPServletInvoker.cpp b/src/uscxml/plugins/invoker/http/HTTPServletInvoker.cpp new file mode 100644 index 0000000..40f8b66 --- /dev/null +++ b/src/uscxml/plugins/invoker/http/HTTPServletInvoker.cpp @@ -0,0 +1,147 @@ +#include "HTTPServletInvoker.h" +#include <glog/logging.h> + +#ifdef BUILD_AS_PLUGINS +#include <Pluma/Connector.hpp> +#endif + +namespace uscxml { + +#ifdef BUILD_AS_PLUGINS +PLUMA_CONNECTOR +bool connect(pluma::Host& host) { + host.add( new HTTPServletInvokerProvider() ); + return true; +} +#endif + +HTTPServletInvoker::HTTPServletInvoker() { + _isInterpreterGlobal = false; +} + +HTTPServletInvoker::HTTPServletInvoker(Interpreter* interpreter) { + _isInterpreterGlobal = true; + _interpreter = interpreter; + std::stringstream path; + path << _interpreter->getName(); + int i = 2; + while(!HTTPServer::registerServlet(path.str(), this)) { + path.clear(); + path.str(); + path << _interpreter->getName() << toStr(i++); + } +} + +HTTPServletInvoker::~HTTPServletInvoker() { + HTTPServer::unregisterServlet(this); + +}; + +boost::shared_ptr<IOProcessorImpl> HTTPServletInvoker::create(Interpreter* interpreter) { + boost::shared_ptr<HTTPServletInvoker> invoker = boost::shared_ptr<HTTPServletInvoker>(new HTTPServletInvoker()); + invoker->_interpreter = interpreter; + return invoker; +} + +Data HTTPServletInvoker::getDataModelVariables() { + Data data; + assert(_url.length() > 0); + data.compound["location"] = Data(_url, Data::VERBATIM); + return data; +} + +void HTTPServletInvoker::send(const SendRequest& req) { + assert(!_isInterpreterGlobal); + + if (req.name.find("reply.", 0, req.name.length())) { + // this is a reply + const std::string requestId = req.name.substr(6); + if (_requests.find(requestId) == _requests.end()) { + LOG(ERROR) << "Replying to non existing request " << requestId; + return; + } + + HTTPServer::Request httpRequest = _requests[requestId]; + HTTPServer::Reply httpReply(httpRequest); + httpReply.content = req.content; + + std::map<std::string, std::string>::const_iterator nameListIter = req.namelist.begin(); + while(nameListIter != req.namelist.end()) { + httpReply.headers[nameListIter->first] = nameListIter->second; + nameListIter++; + } + + std::multimap<std::string, std::string>::const_iterator paramIter = req.params.begin(); + while(paramIter != req.params.end()) { + httpReply.headers[paramIter->first] = paramIter->second; + paramIter++; + } + + HTTPServer::reply(httpReply); + return; + } +} + +void HTTPServletInvoker::cancel(const std::string sendId) { + assert(!_isInterpreterGlobal); +} + +void HTTPServletInvoker::invoke(const InvokeRequest& req) { + assert(!_isInterpreterGlobal); + + _invokeId = req.invokeid; + if (req.params.find("path") == req.params.end()) { + LOG(ERROR) << "Path parameter required with httpserver"; + } + _path = (*req.params.find("path")).second; + + if (req.params.find("callback") != req.params.end()) { + _callback = (*req.params.find("callback")).second; + } else { + _callback = _path; + std::replace(_callback.begin(), _callback.end(), '/', '.'); + } + + if (!HTTPServer::registerServlet(_path, this)) { + LOG(ERROR) << "Cannot register http servlet at " << _path << ": " << " already taken"; + } +} + +/** + * Receive a request and deliver it to the interpreter + */ +void HTTPServletInvoker::httpRecvRequest(const HTTPServer::Request& req) { + tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); + +// evhttp_request_own(req.curlReq); + + _requests[toStr((uintptr_t)req.curlReq)] = req; + + Event event; + + if (_isInterpreterGlobal) { + event.name = "http." + req.type; + event.origin = toStr((uintptr_t)req.curlReq); + } else { + event.name = _callback; + event.data.compound["reqId"] = Data(toStr((uintptr_t)req.curlReq), Data::VERBATIM); + } + + std::map<std::string, std::string>::const_iterator headerIter = req.headers.begin(); + while(headerIter != req.headers.end()) { + event.data.compound["headers"].compound[headerIter->first] = Data(headerIter->second, Data::VERBATIM); + headerIter++; + } + + event.data.compound["content"] = Data(req.content, Data::VERBATIM); + event.data.compound["type"] = Data(req.type, Data::VERBATIM); + + returnEvent(event); + +} + +std::string HTTPServletInvoker::getPath() { + return _path; +} + +}
\ No newline at end of file diff --git a/src/uscxml/plugins/invoker/http/HTTPServletInvoker.h b/src/uscxml/plugins/invoker/http/HTTPServletInvoker.h new file mode 100644 index 0000000..1d667de --- /dev/null +++ b/src/uscxml/plugins/invoker/http/HTTPServletInvoker.h @@ -0,0 +1,55 @@ +#ifndef HTTPSERVERINVOKER_H_OAAWX8NF +#define HTTPSERVERINVOKER_H_OAAWX8NF + +#include <uscxml/Interpreter.h> +#include <uscxml/server/HTTPServer.h> + +#ifdef BUILD_AS_PLUGINS +#include "uscxml/plugins/Plugins.h" +#endif + +namespace uscxml { + +class HTTPServletInvoker : public InvokerImpl, public HTTPServlet { +public: + HTTPServletInvoker(); + HTTPServletInvoker(Interpreter* interpreter); + virtual ~HTTPServletInvoker(); + virtual boost::shared_ptr<IOProcessorImpl> create(Interpreter* interpreter); + + virtual std::set<std::string> getNames() { + std::set<std::string> names; + names.insert("httpserver"); + names.insert("http://uscxml.tk.informatik.tu-darmstadt.de/#httpserver"); + return names; + } + + virtual Data getDataModelVariables(); + virtual void send(const SendRequest& req); + virtual void cancel(const std::string sendId); + virtual void invoke(const InvokeRequest& req); + + // HTTPServlet + virtual void httpRecvRequest(const HTTPServer::Request& req); + virtual std::string getPath(); + virtual void setURL(const std::string& url) { _url = url; } + + tthread::recursive_mutex& getMutex() { return _mutex; } + std::map<std::string, HTTPServer::Request>& getRequests() { return _requests; } + +protected: + tthread::recursive_mutex _mutex; + std::map<std::string, HTTPServer::Request> _requests; + std::string _path; + std::string _callback; + std::string _url; + bool _isInterpreterGlobal; +}; + +#ifdef BUILD_AS_PLUGINS +PLUMA_INHERIT_PROVIDER(HTTPServletInvoker, Invoker); +#endif + +} + +#endif /* end of include guard: HTTPSERVERINVOKER_H_OAAWX8NF */ diff --git a/src/uscxml/plugins/invoker/umundo/UmundoInvoker.cpp b/src/uscxml/plugins/invoker/umundo/UmundoInvoker.cpp index 1e15865..4005d03 100644 --- a/src/uscxml/plugins/invoker/umundo/UmundoInvoker.cpp +++ b/src/uscxml/plugins/invoker/umundo/UmundoInvoker.cpp @@ -77,7 +77,7 @@ void UmundoInvoker::send(const SendRequest& req) { Event event; void* rv = NULL; stub->callStubMethod(req.name, pbMsg, type, rv, ""); - protobufToData(event, *(const google::protobuf::Message*)rv); + protobufToData(event.data, *(const google::protobuf::Message*)rv); event.name = _invokeId + ".reply." + req.name; event.origin = msg->getMeta("um.channel"); @@ -162,9 +162,9 @@ void UmundoInvoker::invoke(const InvokeRequest& req) { } else if (serviceName.length() > 0) { // use umundo to access services - _svcFilter = umundo::ServiceFilter(serviceName); - _node->connect(&_svcMgr); - _svcMgr.startQuery(_svcFilter, this); + _svcFilter = new umundo::ServiceFilter(serviceName); + _node->connect(_svcMgr); + _svcMgr->startQuery(*_svcFilter, this); } } @@ -185,13 +185,13 @@ void UmundoInvoker::receive(void* object, umundo::Message* msg) { // event.compound["class"] = msg->getMeta("um.s11n.type"); if (object != NULL) - protobufToData(event, *(const google::protobuf::Message*)object); + protobufToData(event.data, *(const google::protobuf::Message*)object); // get meta fields into event std::map<std::string, std::string>::const_iterator metaIter = msg->getMeta().begin(); while(metaIter != msg->getMeta().end()) { if (metaIter->first.substr(0,3).compare("um.") != 0) - event.compound[metaIter->first] = Data(metaIter->second, Data::VERBATIM); + event.data.compound[metaIter->first] = Data(metaIter->second, Data::VERBATIM); metaIter++; } @@ -213,7 +213,7 @@ void UmundoInvoker::added(umundo::ServiceDescription desc) { std::map<std::string, std::string>::const_iterator propIter = desc.getProperties().begin(); while(propIter != desc.getProperties().end()) { - addedEvent.compound[propIter->first] = Data(propIter->second, Data::VERBATIM); + addedEvent.data.compound[propIter->first] = Data(propIter->second, Data::VERBATIM); propIter++; } @@ -239,7 +239,7 @@ void UmundoInvoker::removed(umundo::ServiceDescription desc) { std::map<std::string, std::string>::const_iterator propIter = desc.getProperties().begin(); while(propIter != desc.getProperties().end()) { - addedEvent.compound[propIter->first] = Data(propIter->second, Data::VERBATIM); + addedEvent.data.compound[propIter->first] = Data(propIter->second, Data::VERBATIM); propIter++; } diff --git a/src/uscxml/plugins/invoker/umundo/UmundoInvoker.h b/src/uscxml/plugins/invoker/umundo/UmundoInvoker.h index f03006b..a7f45f1 100644 --- a/src/uscxml/plugins/invoker/umundo/UmundoInvoker.h +++ b/src/uscxml/plugins/invoker/umundo/UmundoInvoker.h @@ -1,12 +1,12 @@ #ifndef UMUNDOINVOKER_H_77YXQGU7 #define UMUNDOINVOKER_H_77YXQGU7 +#include <uscxml/Interpreter.h> +#include <google/protobuf/message.h> #include <umundo/core.h> #include <umundo/s11n.h> #include <umundo/rpc.h> #include <umundo/s11n/protobuf/PBSerializer.h> -#include <uscxml/Interpreter.h> -#include <google/protobuf/message.h> #ifdef BUILD_AS_PLUGINS #include "uscxml/plugins/Plugins.h" @@ -51,8 +51,8 @@ protected: umundo::TypedPublisher* _pub; umundo::TypedSubscriber* _sub; - umundo::ServiceFilter _svcFilter; - umundo::ServiceManager _svcMgr; + umundo::ServiceFilter* _svcFilter; + umundo::ServiceManager* _svcMgr; std::map<umundo::ServiceDescription, umundo::ServiceStub*> _svcs; static std::multimap<std::string, std::pair<std::string, umundo::Node*> > _nodes; |