From c78b469790301e3353b561137839c4a2e2ba1673 Mon Sep 17 00:00:00 2001 From: Stefan Radomski Date: Sat, 15 Dec 2012 20:11:05 +0100 Subject: Github client hiccup --- src/uscxml/datamodel/ecmascript/v8/V8DataModel.h | 78 ---- src/uscxml/invoker/umundo/UmundoInvoker.cpp | 485 --------------------- src/uscxml/invoker/umundo/UmundoInvoker.h | 56 --- .../basichttp/libevent/EventIOProcessor.cpp | 358 --------------- .../basichttp/libevent/EventIOProcessor.h | 92 ---- 5 files changed, 1069 deletions(-) delete mode 100644 src/uscxml/datamodel/ecmascript/v8/V8DataModel.h delete mode 100644 src/uscxml/invoker/umundo/UmundoInvoker.cpp delete mode 100644 src/uscxml/invoker/umundo/UmundoInvoker.h delete mode 100644 src/uscxml/ioprocessor/basichttp/libevent/EventIOProcessor.cpp delete mode 100644 src/uscxml/ioprocessor/basichttp/libevent/EventIOProcessor.h diff --git a/src/uscxml/datamodel/ecmascript/v8/V8DataModel.h b/src/uscxml/datamodel/ecmascript/v8/V8DataModel.h deleted file mode 100644 index 25d0e1a..0000000 --- a/src/uscxml/datamodel/ecmascript/v8/V8DataModel.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef V8DATAMODEL_H_KN8TWG0V -#define V8DATAMODEL_H_KN8TWG0V - -#include "uscxml/Interpreter.h" -#include -#include - -namespace uscxml { - class Event; - class Data; - class V8SCXMLDOM; -} - -namespace uscxml { - -class V8DataModel : public DataModel { -public: - V8DataModel(); - virtual ~V8DataModel(); - virtual DataModel* create(Interpreter* interpreter); - - virtual void initialize(); - virtual void setSessionId(const std::string& sessionId); - virtual void setName(const std::string& name); - virtual void setEvent(const Event& event); - - virtual bool validate(const std::string& location, const std::string& schema); - - virtual uint32_t getLength(const std::string& expr); - virtual void pushContext(); - virtual void popContext(); - - virtual void eval(const std::string& expr); - virtual void assign(const std::string& location, const std::string& expr); - virtual void assign(const std::string& location, const Data& data); - - virtual Data getStringAsData(const std::string& content); - virtual Data getValueAsData(const v8::Handle& value); - - virtual std::string evalAsString(const std::string& expr); - virtual bool evalAsBool(const std::string& expr); - - static v8::Handle jsGetEventName(v8::Local property, - const v8::AccessorInfo &info); - static v8::Handle jsGetEventType(v8::Local property, - const v8::AccessorInfo &info); - static v8::Handle jsGetEventSendId(v8::Local property, - const v8::AccessorInfo &info); - static v8::Handle jsGetEventOrigin(v8::Local property, - const v8::AccessorInfo &info); - static v8::Handle jsGetEventOriginType(v8::Local property, - const v8::AccessorInfo &info); - static v8::Handle jsGetEventInvokeId(v8::Local property, - const v8::AccessorInfo &info); - - static v8::Handle jsIn(const v8::Arguments& args); - static v8::Handle jsPrint(const v8::Arguments& args); - - -protected: - std::list > _contexts; - Interpreter* _interpreter; - - std::string _sessionId; - std::string _name; - - Event _event; - v8::Persistent _globalTemplate; - v8::Persistent _eventTemplate; - - v8::Handle evalAsValue(const std::string& expr); - virtual v8::Handle getDataAsValue(const Data& data); - -}; - -} - -#endif /* end of include guard: V8DATAMODEL_H_KN8TWG0V */ diff --git a/src/uscxml/invoker/umundo/UmundoInvoker.cpp b/src/uscxml/invoker/umundo/UmundoInvoker.cpp deleted file mode 100644 index 5f6a552..0000000 --- a/src/uscxml/invoker/umundo/UmundoInvoker.cpp +++ /dev/null @@ -1,485 +0,0 @@ -#include "uscxml/Common.h" -#include "UmundoInvoker.h" -#include "uscxml/Interpreter.h" -#include - -namespace uscxml { - -UmundoInvoker::UmundoInvoker() { - _sub = NULL; - _pub = NULL; - _svcMgr = NULL; - _svcFilter = NULL; -} - -UmundoInvoker::~UmundoInvoker() { - if (_sub != NULL) { - _node->removeSubscriber(_sub); - } - if (_pub != NULL) { - _node->removePublisher(_pub); - } -}; - -Invoker* UmundoInvoker::create(Interpreter* interpreter) { - UmundoInvoker* invoker = new UmundoInvoker(); - invoker->_interpreter = interpreter; - return invoker; -} - -Data UmundoInvoker::getDataModelVariables() { - Data data; - return data; -} - -void UmundoInvoker::send(SendRequest& req) { - umundo::Message* msg = new umundo::Message(); - - if (req.name.length() > 0) { - msg->putMeta("event", req.name); - } else { - msg->putMeta("event", "umundo"); - } - - if (req.params.find("type") != req.params.end()) { - // assume JSON in content to transform to protobuf object - if (req.content.length() > 0 && _interpreter->getDataModel() != NULL) { - std::string type = req.params["type"].front(); - const google::protobuf::Message* protoMsg = umundo::PBSerializer::getProto(type); - if (protoMsg == NULL) { - LOG(ERROR) << "No type " << type << " is known, pass a directory with proto .desc files via types param when invoking"; - return; - } - try { - Data data = _interpreter->getDataModel()->getStringAsData(req.content); - google::protobuf::Message* pbMsg = protoMsg->New(); - if (!dataToProtobuf(pbMsg, data)) { - LOG(ERROR) << "Cannot create message from JSON - not sending"; - } else { - // add all s11n properties - if (!_isService) { - _pub->prepareMsg(msg, type, pbMsg); - _pub->send(msg); - } else { - std::map, umundo::ServiceStub*>::iterator svcIter = _svcs.begin(); - while(svcIter != _svcs.end()) { - umundo::ServiceStub* stub = svcIter->second; - Event event; - void* rv = NULL; - stub->callStubMethod(req.name, pbMsg, type, rv, ""); - protobufToData(event, *(const google::protobuf::Message*)rv); - - event.name = _invokeId + ".reply." + req.name; - event.invokeid = _invokeId; - event.origin = msg->getMeta("um.channel"); - event.origintype = "umundo"; - event.type = Event::EXTERNAL; - - _interpreter->receive(event); - svcIter++; - } - } - } - } catch (Event e) { - LOG(ERROR) << "Syntax error when invoking umundo:" << std::endl << e << std::endl; - return; - } - } else { - LOG(ERROR) << "Required JSON object in content" << std::endl; - return; - } - } -} - -void UmundoInvoker::cancel(const std::string sendId) { - assert(false); -} - -void UmundoInvoker::sendToParent(SendRequest& req) { - assert(false); -} - -void UmundoInvoker::invoke(InvokeRequest& req) { - _invokeId = req.invokeid; - - std::string channelName; - std::string serviceName; - - if (req.params.find("channel") != req.params.end()) { - channelName = req.params["channel"].front(); - _isService = false; - } else if (req.params.find("service") != req.params.end()) { - serviceName = req.params["service"].front(); - _isService = true; - } else { - LOG(ERROR) << "Invoking umundo needs a service or a channel param"; - return; - } - - _node = getNode(_interpreter); - - // add types from .proto or .desc files - if (req.params.find("types") != req.params.end()) { - std::list::iterator typeIter = req.params["types"].begin(); - while(typeIter != req.params["types"].end()) { - Arabica::io::URI srcURI(*typeIter); - if (!_interpreter->makeAbsolute(srcURI)) { - LOG(ERROR) << "Relative URI for types in umundo invoker " << *typeIter << " with no base URI set for interpreter"; - return; - } - umundo::PBSerializer::addProto(srcURI.path()); - typeIter++; - } - } - - if (!_isService) { - // use umundo to publish objects on a channel - _pub = new umundo::TypedPublisher(channelName); - _sub = new umundo::TypedSubscriber(channelName, this); - - _node->addPublisher(_pub); - _node->addSubscriber(_sub); - - } else if (serviceName.length() > 0) { - // use umundo to access services - _svcFilter = new umundo::ServiceFilter(serviceName); - _svcMgr = new umundo::ServiceManager(); - _node->connect(_svcMgr); - _svcMgr->startQuery(_svcFilter, this); - } -} - -void UmundoInvoker::receive(void* object, umundo::Message* msg) { - uscxml::Event event; - if (msg->getMeta().find("event") != msg->getMeta().end()) { - event.name = msg->getMeta("event"); - } else { - event.name = "umundo.rcvd"; - } - - event.invokeid = _invokeId; - event.origin = msg->getMeta("um.channel"); - event.origintype = "umundo"; - event.type = Event::EXTERNAL; - -// if (msg->getMeta().find("um.s11n.type") != msg->getMeta().end()) -// event.compound["class"] = msg->getMeta("um.s11n.type"); - - if (object != NULL) - protobufToData(event, *(const google::protobuf::Message*)object); - - // get meta fields into event - std::map::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); - metaIter++; - } - - _interpreter->receive(event); -} - -void UmundoInvoker::added(boost::shared_ptr desc) { - LOG(ERROR) << "Service found!"; - - umundo::ServiceStub* stub = new umundo::ServiceStub(desc.get()); - _svcs[desc] = stub; - - Event addedEvent; - addedEvent.invokeid = _invokeId; - addedEvent.origin = desc->getName(); - addedEvent.origintype = "umundo"; - addedEvent.type = Event::EXTERNAL; - addedEvent.name = _invokeId + ".added"; - - std::map::const_iterator propIter = desc->getProperties().begin(); - while(propIter != desc->getProperties().end()) { - addedEvent.compound[propIter->first] = Data(propIter->second, Data::VERBATIM); - propIter++; - } - - _interpreter->receive(addedEvent); -} - -void UmundoInvoker::removed(boost::shared_ptr desc) { - LOG(ERROR) << "Service lost!"; - - if (_svcs.find(desc) == _svcs.end()) { - return; - } - - delete _svcs[desc]; - _svcs.erase(desc); - - Event addedEvent; - addedEvent.invokeid = _invokeId; - addedEvent.origin = desc->getName(); - addedEvent.origintype = "umundo"; - addedEvent.type = Event::EXTERNAL; - addedEvent.name = _invokeId + ".removed"; - - std::map::const_iterator propIter = desc->getProperties().begin(); - while(propIter != desc->getProperties().end()) { - addedEvent.compound[propIter->first] = Data(propIter->second, Data::VERBATIM); - propIter++; - } - - _interpreter->receive(addedEvent); -} - -void UmundoInvoker::changed(boost::shared_ptr desc) { -} - -std::map > UmundoInvoker::_nodes; -boost::shared_ptr UmundoInvoker::getNode(Interpreter* interpreter) { - if ((_nodes.find(interpreter->getName()) == _nodes.end()) || _nodes[interpreter->getName()].expired()) { - boost::shared_ptr node = boost::shared_ptr(new umundo::Node()); - _nodes[interpreter->getName()] = node; - return node; - } - return _nodes[interpreter->getName()].lock(); -} - -bool UmundoInvoker::protobufToData(Data& data, const google::protobuf::Message& msg) { - const google::protobuf::Descriptor* desc = msg.GetDescriptor(); - const google::protobuf::Reflection* reflect = msg.GetReflection(); - - data.compound["type"] = Data(desc->name(), Data::VERBATIM); - - for (int i = 0; i < desc->field_count(); i++) { - const google::protobuf::FieldDescriptor* fieldDesc = desc->field(i); - std::string key = fieldDesc->name(); - - if (!fieldDesc->is_repeated() && !reflect->HasField(msg, fieldDesc)) - continue; - - switch(fieldDesc->type()) { - case google::protobuf::FieldDescriptor::TYPE_BOOL: - if (fieldDesc->is_repeated()) { - for (int j = 0; j < reflect->FieldSize(msg, fieldDesc); j++) { - data.compound[key].array.push_back(Data(reflect->GetRepeatedBool(msg, fieldDesc, j) ? "true" : "false")); - } - } else { - data.compound[key].atom = (reflect->GetBool(msg, fieldDesc) ? "true" : "false"); - } - break; - case google::protobuf::FieldDescriptor::TYPE_BYTES: - case google::protobuf::FieldDescriptor::TYPE_STRING: - if (fieldDesc->is_repeated()) { - for (int j = 0; j < reflect->FieldSize(msg, fieldDesc); j++) { - data.compound[key].array.push_back(Data(toStr(reflect->GetRepeatedString(msg, fieldDesc, j)), Data::VERBATIM)); - } - } else { - data.compound[key].atom = toStr(reflect->GetString(msg, fieldDesc)); - data.compound[key].type = Data::VERBATIM; - } - break; - case google::protobuf::FieldDescriptor::TYPE_DOUBLE: - if (fieldDesc->is_repeated()) { - for (int j = 0; j < reflect->FieldSize(msg, fieldDesc); j++) { - data.compound[key].array.push_back(Data(toStr(reflect->GetRepeatedDouble(msg, fieldDesc, j)))); - } - } else { - data.compound[key].atom = toStr(reflect->GetDouble(msg, fieldDesc)); - } - break; - case google::protobuf::FieldDescriptor::TYPE_ENUM: - LOG(ERROR) << "TYPE_ENUM is unimplemented" << std::endl; - break; - case google::protobuf::FieldDescriptor::TYPE_FIXED32: - case google::protobuf::FieldDescriptor::TYPE_UINT32: - if (fieldDesc->is_repeated()) { - for (int j = 0; j < reflect->FieldSize(msg, fieldDesc); j++) { - data.compound[key].array.push_back(Data(toStr(reflect->GetRepeatedUInt32(msg, fieldDesc, j)))); - } - } else { - data.compound[key].atom = toStr(reflect->GetUInt32(msg, fieldDesc)); - } - break; - case google::protobuf::FieldDescriptor::TYPE_FIXED64: - case google::protobuf::FieldDescriptor::TYPE_UINT64: - if (fieldDesc->is_repeated()) { - for (int j = 0; j < reflect->FieldSize(msg, fieldDesc); j++) { - data.compound[key].array.push_back(Data(toStr(reflect->GetRepeatedUInt64(msg, fieldDesc, j)))); - } - } else { - data.compound[key].atom = toStr(reflect->GetUInt64(msg, fieldDesc)); - } - break; - case google::protobuf::FieldDescriptor::TYPE_FLOAT: - if (fieldDesc->is_repeated()) { - for (int j = 0; j < reflect->FieldSize(msg, fieldDesc); j++) { - data.compound[key].array.push_back(Data(toStr(reflect->GetRepeatedFloat(msg, fieldDesc, j)))); - } - } else { - data.compound[key].atom = toStr(reflect->GetFloat(msg, fieldDesc)); - } - break; - case google::protobuf::FieldDescriptor::TYPE_GROUP: - LOG(ERROR) << "TYPE_GROUP is unimplemented" << std::endl; - break; - case google::protobuf::FieldDescriptor::TYPE_INT32: - case google::protobuf::FieldDescriptor::TYPE_SINT32: - case google::protobuf::FieldDescriptor::TYPE_SFIXED32: - if (fieldDesc->is_repeated()) { - for (int j = 0; j < reflect->FieldSize(msg, fieldDesc); j++) { - data.compound[key].array.push_back(Data(toStr(reflect->GetRepeatedInt32(msg, fieldDesc, j)))); - } - } else { - data.compound[key].atom = toStr(reflect->GetInt32(msg, fieldDesc)); - } - break; - case google::protobuf::FieldDescriptor::TYPE_INT64: - case google::protobuf::FieldDescriptor::TYPE_SINT64: - case google::protobuf::FieldDescriptor::TYPE_SFIXED64: - if (fieldDesc->is_repeated()) { - for (int j = 0; j < reflect->FieldSize(msg, fieldDesc); j++) { - data.compound[key].array.push_back(Data(toStr(reflect->GetRepeatedInt64(msg, fieldDesc, j)))); - } - } else { - data.compound[key].atom = toStr(reflect->GetInt64(msg, fieldDesc)); - } - break; - case google::protobuf::FieldDescriptor::TYPE_MESSAGE: - if (fieldDesc->is_repeated()) { - for (int j = 0; j < reflect->FieldSize(msg, fieldDesc); j++) { - data.compound[key].array.push_back(Data()); - protobufToData(data.compound[key].array.back(), reflect->GetRepeatedMessage(msg, fieldDesc, j)); - } - } else { - protobufToData(data.compound[key], reflect->GetMessage(msg, fieldDesc)); - } - break; - } - } - return true; -} - -bool UmundoInvoker::dataToProtobuf(google::protobuf::Message* msg, Data& data) { - const google::protobuf::Descriptor* desc = msg->GetDescriptor(); - const google::protobuf::Reflection* reflect = msg->GetReflection(); - - for (int i = 0; i < desc->field_count(); i++) { - const google::protobuf::FieldDescriptor* fieldDesc = desc->field(i); - std::string key = fieldDesc->name(); - - if (data.compound.find(key) == data.compound.end()) { - if (fieldDesc->is_required()) { - LOG(ERROR) << "required field " << key << " not given in JSON"; - return false; - } - continue; - } - - std::list::iterator arrayIter = data.compound[key].array.begin(); - - switch(fieldDesc->type()) { - case google::protobuf::FieldDescriptor::TYPE_BOOL: - if (fieldDesc->is_repeated()) { - while(arrayIter != data.compound[key].array.end()) { - reflect->AddBool(msg, fieldDesc, arrayIter->atom.compare("false") == 0 ? false : true); - arrayIter++; - } - } else { - reflect->SetBool(msg, fieldDesc, (data.compound[key].atom.compare("false") == 0 ? false : true)); - } - break; - case google::protobuf::FieldDescriptor::TYPE_BYTES: - case google::protobuf::FieldDescriptor::TYPE_STRING: - if (fieldDesc->is_repeated()) { - while(arrayIter != data.compound[key].array.end()) { - reflect->AddString(msg, fieldDesc, arrayIter->atom); - arrayIter++; - } - } else { - reflect->SetString(msg, fieldDesc, data.compound[key].atom); - } - break; - case google::protobuf::FieldDescriptor::TYPE_DOUBLE: - if (fieldDesc->is_repeated()) { - while(arrayIter != data.compound[key].array.end()) { - reflect->AddDouble(msg, fieldDesc, strTo(arrayIter->atom)); - arrayIter++; - } - } else { - reflect->SetDouble(msg, fieldDesc, strTo(data.compound[key].atom)); - } - break; - case google::protobuf::FieldDescriptor::TYPE_ENUM: - LOG(ERROR) << "TYPE_ENUM is unimplemented" << std::endl; - break; - case google::protobuf::FieldDescriptor::TYPE_FIXED32: - case google::protobuf::FieldDescriptor::TYPE_UINT32: - if (fieldDesc->is_repeated()) { - while(arrayIter != data.compound[key].array.end()) { - reflect->AddUInt32(msg, fieldDesc, strTo(arrayIter->atom)); - arrayIter++; - } - } else { - reflect->SetUInt32(msg, fieldDesc, strTo(data.compound[key].atom)); - } - break; - case google::protobuf::FieldDescriptor::TYPE_FIXED64: - case google::protobuf::FieldDescriptor::TYPE_UINT64: - if (fieldDesc->is_repeated()) { - while(arrayIter != data.compound[key].array.end()) { - reflect->AddUInt64(msg, fieldDesc, strTo(arrayIter->atom)); - arrayIter++; - } - } else { - reflect->SetUInt64(msg, fieldDesc, strTo(data.compound[key].atom)); - } - break; - case google::protobuf::FieldDescriptor::TYPE_FLOAT: - if (fieldDesc->is_repeated()) { - while(arrayIter != data.compound[key].array.end()) { - reflect->AddFloat(msg, fieldDesc, strTo(arrayIter->atom)); - arrayIter++; - } - } else { - reflect->SetFloat(msg, fieldDesc, strTo(data.compound[key].atom)); - } - break; - case google::protobuf::FieldDescriptor::TYPE_GROUP: - LOG(ERROR) << "TYPE_GROUP is unimplemented" << std::endl; - break; - case google::protobuf::FieldDescriptor::TYPE_INT32: - case google::protobuf::FieldDescriptor::TYPE_SINT32: - case google::protobuf::FieldDescriptor::TYPE_SFIXED32: - if (fieldDesc->is_repeated()) { - while(arrayIter != data.compound[key].array.end()) { - reflect->AddInt32(msg, fieldDesc, strTo(arrayIter->atom)); - arrayIter++; - } - } else { - reflect->SetInt32(msg, fieldDesc, strTo(data.compound[key].atom)); - } - break; - case google::protobuf::FieldDescriptor::TYPE_INT64: - case google::protobuf::FieldDescriptor::TYPE_SINT64: - case google::protobuf::FieldDescriptor::TYPE_SFIXED64: - if (fieldDesc->is_repeated()) { - while(arrayIter != data.compound[key].array.end()) { - reflect->AddInt64(msg, fieldDesc, strTo(arrayIter->atom)); - arrayIter++; - } - } else { - reflect->SetInt64(msg, fieldDesc, strTo(data.compound[key].atom)); - } - break; - case google::protobuf::FieldDescriptor::TYPE_MESSAGE: - if (fieldDesc->is_repeated()) { - while(arrayIter != data.compound[key].array.end()) { - dataToProtobuf(reflect->AddMessage(msg, fieldDesc), *arrayIter); - arrayIter++; - } - } else { - dataToProtobuf(reflect->MutableMessage(msg, fieldDesc), data.compound[key]); - } - break; - } - } - return true; -} - -} \ No newline at end of file diff --git a/src/uscxml/invoker/umundo/UmundoInvoker.h b/src/uscxml/invoker/umundo/UmundoInvoker.h deleted file mode 100644 index 080fc3c..0000000 --- a/src/uscxml/invoker/umundo/UmundoInvoker.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef UMUNDOINVOKER_H_77YXQGU7 -#define UMUNDOINVOKER_H_77YXQGU7 - -#include -#include -#include -#include -#include -#include "uscxml/Factory.h" - -namespace uscxml { - -class Interpreter; - -class UmundoInvoker : public Invoker, public umundo::TypedReceiver, public umundo::ResultSet { -public: - UmundoInvoker(); - virtual ~UmundoInvoker(); - virtual Invoker* create(Interpreter* interpreter); - - virtual Data getDataModelVariables(); - virtual void send(SendRequest& req); - virtual void cancel(const std::string sendId); - virtual void invoke(InvokeRequest& req); - virtual void sendToParent(SendRequest& req); - - virtual void receive(void* object, umundo::Message* msg); - - virtual void added(boost::shared_ptr); - virtual void removed(boost::shared_ptr); - virtual void changed(boost::shared_ptr); - -protected: - std::string _invokeId; - Interpreter* _interpreter; - bool _isService; - - bool dataToProtobuf(google::protobuf::Message* msg, Data& data); - bool protobufToData(Data& data, const google::protobuf::Message& msg); - - umundo::TypedPublisher* _pub; - umundo::TypedSubscriber* _sub; - boost::shared_ptr _node; - - umundo::ServiceFilter* _svcFilter; - umundo::ServiceManager* _svcMgr; - std::map, umundo::ServiceStub*> _svcs; - - static std::map > _nodes; - static boost::shared_ptr getNode(Interpreter* interpreter); -}; - -} - - -#endif /* end of include guard: UMUNDOINVOKER_H_77YXQGU7 */ diff --git a/src/uscxml/ioprocessor/basichttp/libevent/EventIOProcessor.cpp b/src/uscxml/ioprocessor/basichttp/libevent/EventIOProcessor.cpp deleted file mode 100644 index d41854a..0000000 --- a/src/uscxml/ioprocessor/basichttp/libevent/EventIOProcessor.cpp +++ /dev/null @@ -1,358 +0,0 @@ -#ifdef _WIN32 -#include -#include -#endif - -#include "uscxml/ioprocessor/basichttp/libevent/EventIOProcessor.h" -#include "uscxml/Message.h" -#include -#include -#include -#include - -#include - -#include -#include - -#ifndef _WIN32 -#include -#include -#endif - -namespace uscxml { - -// see http://www.w3.org/TR/scxml/#BasicHTTPEventProcessor - -EventIOProcessor::EventIOProcessor() { -} - -EventIOProcessor::~EventIOProcessor() { - _asyncQueue.stop(); - evdns_base_free(_dns, 1); - EventIOServer* httpServer = EventIOServer::getInstance(); - httpServer->unregisterProcessor(this); -} - -IOProcessor* EventIOProcessor::create(Interpreter* interpreter) { - EventIOProcessor* io = new EventIOProcessor(); - io->_interpreter = interpreter; - - io->_dns = evdns_base_new(io->_asyncQueue._eventLoop, 1); - assert(io->_dns); - assert(evdns_base_count_nameservers(io->_dns) > 0); - - // register at http server - EventIOServer* httpServer = EventIOServer::getInstance(); - httpServer->registerProcessor(io); - - io->start(); - return io; -} - -void EventIOProcessor::start() { - _asyncQueue.start(); -} - -Data EventIOProcessor::getDataModelVariables() { - Data data; - assert(_url.length() > 0); - data.compound["location"] = Data(_url, Data::VERBATIM); - return data; -} - - -void EventIOProcessor::send(SendRequest& req) { - // I cant figure out how to copy the reference into the struct :( - _sendData[req.sendid].req = req; - _sendData[req.sendid].ioProcessor = this; - - int err = 0; - char uriBuf[1024]; - - struct evhttp_uri* targetURI = evhttp_uri_parse(_sendData[req.sendid].req.target.c_str()); - if (evhttp_uri_get_port(targetURI) == 0) - evhttp_uri_set_port(targetURI, 80); - const char* hostName = evhttp_uri_get_host(targetURI); - - // use synchronous dns resolving for multicast dns - if(hostName && strlen(hostName) >= strlen(".local")) { - if(strcmp(hostName + strlen(hostName) - strlen(".local"), ".local") == 0) { - evhttp_uri_set_host(targetURI, EventIOServer::syncResolve(hostName).c_str()); - } - } - evhttp_uri_join(targetURI, uriBuf, 1024); - - LOG(INFO) << "URI for send request: " << uriBuf << std::endl; - - std::stringstream ssEndPoint; - ssEndPoint << evhttp_uri_get_host(targetURI) << ":" << evhttp_uri_get_port(targetURI); - std::string endPoint = ssEndPoint.str(); - - std::stringstream ssLocalURI; - ssLocalURI << evhttp_uri_get_path(targetURI) << evhttp_uri_get_fragment(targetURI); - std::string localURI = ssLocalURI.str(); - - if (_httpConnections.find(endPoint) == _httpConnections.end()) - _httpConnections[endPoint] = evhttp_connection_base_new(_asyncQueue._eventLoop, _dns, evhttp_uri_get_host(targetURI), evhttp_uri_get_port(targetURI)); - - struct evhttp_connection* httpConn = _httpConnections[endPoint]; - struct evhttp_request* httpReq = evhttp_request_new(EventIOProcessor::httpSendReqDone, this); - -#if 0 - // event name - if (sendData->req.event.size() > 0) { - evhttp_add_header(evhttp_request_get_output_headers(httpReq), "_scxmleventname", evhttp_encode_uri(sendData->req.event.c_str())); - } - - // event namelist - if (sendData->req.namelist.size() > 0) { - std::map::iterator namelistIter = sendData->req.namelist.begin(); - while (namelistIter != sendData->req.namelist.end()) { - evhttp_add_header(evhttp_request_get_output_headers(httpReq), - namelistIter->first.c_str(), - evhttp_encode_uri(namelistIter->second.c_str())); - namelistIter++; - } - } - - // event params - if (sendData->req.params.size() > 0) { - std::map::iterator paramIter = sendData->req.params.begin(); - while (paramIter != sendData->req.params.end()) { - evhttp_add_header(evhttp_request_get_output_headers(httpReq), - paramIter->first.c_str(), - evhttp_encode_uri(paramIter->second.c_str())); - paramIter++; - } - } - - // content - if (sendData->req.content.size() > 0) - evbuffer_add(evhttp_request_get_output_buffer(httpReq), sendData->req.content.c_str(), sendData->req.content.size()); -#endif - - evhttp_add_header(evhttp_request_get_output_headers(httpReq), "_scxmleventstruct", evhttp_encode_uri(req.toXMLString().c_str())); - - - _httpRequests[req.sendid] = httpReq; - err = evhttp_make_request(httpConn, - httpReq, - EVHTTP_REQ_POST, localURI.c_str()); - if (err) { - LOG(ERROR) << "Could not make http request to " << req.target; - } -} - -void EventIOProcessor::httpRecvReq(struct evhttp_request *req, void *arg) { - - const char *cmdtype; - struct evkeyvalq *headers; - struct evkeyval *header; - struct evbuffer *buf; - - switch (evhttp_request_get_command(req)) { - case EVHTTP_REQ_GET: cmdtype = "GET"; break; - case EVHTTP_REQ_POST: cmdtype = "POST"; break; - case EVHTTP_REQ_HEAD: cmdtype = "HEAD"; break; - case EVHTTP_REQ_PUT: cmdtype = "PUT"; break; - case EVHTTP_REQ_DELETE: cmdtype = "DELETE"; break; - case EVHTTP_REQ_OPTIONS: cmdtype = "OPTIONS"; break; - case EVHTTP_REQ_TRACE: cmdtype = "TRACE"; break; - case EVHTTP_REQ_CONNECT: cmdtype = "CONNECT"; break; - case EVHTTP_REQ_PATCH: cmdtype = "PATCH"; break; - default: cmdtype = "unknown"; break; - } - - Event reqEvent; - reqEvent.type = Event::EXTERNAL; - bool scxmlStructFound = false; - - // map headers to event structure - headers = evhttp_request_get_input_headers(req); - for (header = headers->tqh_first; header; - header = header->next.tqe_next) { -// std::cout << "Header: " << header->key << std::endl; -// std::cout << "Value: " << evhttp_decode_uri(header->value) << std::endl; - if (boost::iequals("_scxmleventstruct", header->key)) { - reqEvent = Event::fromXML(evhttp_decode_uri(header->value)); - scxmlStructFound = true; - break; - } else if (boost::iequals("_scxmleventname", header->key)) { - reqEvent.name = evhttp_decode_uri(header->value); - } else { - reqEvent.compound[header->key] = Data(evhttp_decode_uri(header->value), Data::VERBATIM); - } - } - - if (!scxmlStructFound) { - // get content into event - std::string content; - buf = evhttp_request_get_input_buffer(req); - while (evbuffer_get_length(buf)) { - int n; - char cbuf[128]; - n = evbuffer_remove(buf, cbuf, sizeof(buf)-1); - if (n > 0) { - content.append(cbuf, n); - } - } - reqEvent.compound["content"] = Data(content, Data::VERBATIM); - } - - EventIOProcessor* INSTANCE = (EventIOProcessor*)arg; - INSTANCE->_interpreter->receive(reqEvent); - - evhttp_send_reply(req, 200, "OK", NULL); -} - -void EventIOProcessor::httpSendReqDone(struct evhttp_request *req, void *cb_arg) { - if (req) { - LOG(INFO) << "got return code " << evhttp_request_get_response_code(req) << std::endl; - } -} - -EventIOServer::EventIOServer(unsigned short port) { - _port = port; - _base = event_base_new(); - _http = evhttp_new(_base); - _handle = NULL; - while((_handle = evhttp_bind_socket_with_handle(_http, INADDR_ANY, _port)) == NULL) { - _port++; - } - determineAddress(); -} - -EventIOServer::~EventIOServer() { -} - -EventIOServer* EventIOServer::_instance = NULL; -tthread::recursive_mutex EventIOServer::_instanceMutex; - -EventIOServer* EventIOServer::getInstance() { - tthread::lock_guard lock(_instanceMutex); - if (_instance == NULL) { - _instance = new EventIOServer(8080); - _instance->start(); - } - return _instance; -} - -void EventIOServer::registerProcessor(EventIOProcessor* processor) { - EventIOServer* INSTANCE = getInstance(); - tthread::lock_guard lock(INSTANCE->_mutex); - - /** - * Determine path for interpreter. - * - * If the interpreter has a name and it is not yet taken, choose it as the path - * for requests. If the interpreters name path is already taken, append digits - * until we have an available path. - * - * If the interpreter does not specify a name, take its sessionid. - */ - - std::string path = processor->_interpreter->getName(); - if (path.size() == 0) { - path = processor->_interpreter->getSessionId(); - } - assert(path.size() > 0); - - std::stringstream actualPath(path); - int i = 1; - while(INSTANCE->_processors.find(actualPath.str()) != INSTANCE->_processors.end()) { - actualPath.str(std::string()); - actualPath.clear(); - actualPath << path << ++i; - } - - std::stringstream processorURL; - processorURL << "http://" << INSTANCE->_address << ":" << INSTANCE->_port << "/" << actualPath.str(); - - INSTANCE->_processors[actualPath.str()] = processor; - processor->setURL(processorURL.str()); - - evhttp_set_cb(INSTANCE->_http, ("/" + actualPath.str()).c_str(), EventIOProcessor::httpRecvReq, processor); -// evhttp_set_cb(THIS->_http, "/", EventIOProcessor::httpRecvReq, processor); -// evhttp_set_gencb(THIS->_http, EventIOProcessor::httpRecvReq, NULL); -} - -void EventIOServer::unregisterProcessor(EventIOProcessor* processor) { - EventIOServer* INSTANCE = getInstance(); - tthread::lock_guard lock(INSTANCE->_mutex); - evhttp_del_cb(INSTANCE->_http, processor->_url.c_str()); -} - -void EventIOServer::start() { - _isRunning = true; - _thread = new tthread::thread(EventIOServer::run, this); -} - -void EventIOServer::run(void* instance) { - EventIOServer* INSTANCE = (EventIOServer*)instance; - while(INSTANCE->_isRunning) { - LOG(INFO) << "Dispatching HTTP Server" << std::endl; - event_base_dispatch(INSTANCE->_base); - } - LOG(INFO) << "HTTP Server stopped" << std::endl; -} - -std::string EventIOServer::syncResolve(const std::string& hostname) { - struct hostent *he; - struct in_addr **addr_list; - int i; - - if ( (he = gethostbyname( hostname.c_str() ) ) != NULL) { - addr_list = (struct in_addr **) he->h_addr_list; - for(i = 0; addr_list[i] != NULL; i++) { - return std::string(inet_ntoa(*addr_list[i])); - } - } - return ""; -} - -void EventIOServer::determineAddress() { - - char hostname[1024]; - gethostname(hostname, 1024); - _address = std::string(hostname); - -#if 0 - struct sockaddr_storage ss; - evutil_socket_t fd; - ev_socklen_t socklen = sizeof(ss); - char addrbuf[128]; - - void *inaddr; - const char *addr; - int got_port = -1; - fd = evhttp_bound_socket_get_fd(_handle); - memset(&ss, 0, sizeof(ss)); - if (getsockname(fd, (struct sockaddr *)&ss, &socklen)) { - perror("getsockname() failed"); - return; - } - - if (ss.ss_family == AF_INET) { - got_port = ntohs(((struct sockaddr_in*)&ss)->sin_port); - inaddr = &((struct sockaddr_in*)&ss)->sin_addr; - } else if (ss.ss_family == AF_INET6) { - got_port = ntohs(((struct sockaddr_in6*)&ss)->sin6_port); - inaddr = &((struct sockaddr_in6*)&ss)->sin6_addr; - } else { - fprintf(stderr, "Weird address family %d\n", - ss.ss_family); - return; - } - addr = evutil_inet_ntop(ss.ss_family, inaddr, addrbuf, - sizeof(addrbuf)); - if (addr) { - _address = std::string(addr); - } else { - fprintf(stderr, "evutil_inet_ntop failed\n"); - return; - } -#endif -} - -} \ No newline at end of file diff --git a/src/uscxml/ioprocessor/basichttp/libevent/EventIOProcessor.h b/src/uscxml/ioprocessor/basichttp/libevent/EventIOProcessor.h deleted file mode 100644 index 7f1cfa1..0000000 --- a/src/uscxml/ioprocessor/basichttp/libevent/EventIOProcessor.h +++ /dev/null @@ -1,92 +0,0 @@ -#ifndef EVENTIOPROCESSOR_H_2CUY93KU -#define EVENTIOPROCESSOR_H_2CUY93KU - -#include "uscxml/concurrency/eventqueue/libevent/DelayedEventQueue.h" -#include "uscxml/Interpreter.h" -#include "uscxml/Factory.h" -#ifndef _WIN32 -#include -#endif - -#include -#include - -namespace uscxml { - -class EventIOServer; - -class EventIOProcessor : public uscxml::IOProcessor { -public: - struct SendData { - EventIOProcessor* ioProcessor; - uscxml::SendRequest req; - }; - - EventIOProcessor(); - virtual ~EventIOProcessor(); - virtual IOProcessor* create(uscxml::Interpreter* interpreter); - - virtual void send(uscxml::SendRequest& req); - - Data getDataModelVariables(); - void setURL(const std::string& url) { _url = url; } - - void start(); - static void run(void* instance); - - static void httpMakeSendReq(void* userdata, std::string eventName); - static void httpSendReqDone(struct evhttp_request *req, void *cb_arg); - static void httpRecvReq(struct evhttp_request *req, void *arg); - -protected: - std::map _sendData; - - std::string _url; - - uscxml::DelayedEventQueue _asyncQueue; - uscxml::Interpreter* _interpreter; - std::map _httpConnections; - std::map _httpRequests; - struct evdns_base* _dns; - - friend class EventIOServer; -}; - -class EventIOServer { -private: - static EventIOServer* getInstance(); - EventIOServer(unsigned short port); - ~EventIOServer(); - - void start(); - void stop(); - static void run(void* instance); - - void determineAddress(); - static std::string syncResolve(const std::string& hostname); - - static void registerProcessor(EventIOProcessor* processor); - static void unregisterProcessor(EventIOProcessor* processor); - - - std::map _processors; - - struct event_base* _base; - struct evhttp* _http; - struct evhttp_bound_socket* _handle; - - unsigned short _port; - std::string _address; - - static EventIOServer* _instance; - static tthread::recursive_mutex _instanceMutex; - tthread::thread* _thread; - tthread::recursive_mutex _mutex; - bool _isRunning; - - friend class EventIOProcessor; -}; - -} - -#endif /* end of include guard: EVENTIOPROCESSOR_H_2CUY93KU */ \ No newline at end of file -- cgit v0.12