From 3451e66f160b05219c02da1f80d3f6515a1742b5 Mon Sep 17 00:00:00 2001 From: matzman Date: Tue, 9 Jun 2015 13:55:31 +0200 Subject: [PATCH] . --- .../webresource/DeviceRepoHandler.cpp | 54 +++++++++---------- .../webresource/DeviceRepoHandler.h | 4 +- .../service/ruleengine/RuleEngineService.h | 7 +++ .../src/BundleActivator.cpp | 2 +- .../ruleengine/RuleEngineServiceImpl.cpp | 11 +++- .../ruleengine/RuleEngineServiceImpl.h | 6 ++- .../webresource/RuleEngineHandler.cpp | 53 ++++++++++++++++-- .../webresource/RuleEngineHandler.h | 7 +-- .../webresource/WebResourceHandlerImpl.h | 1 - 9 files changed, 103 insertions(+), 42 deletions(-) diff --git a/src/hos_cosgi_devicerepository/src/hos/cosgi/service/devicerepository/webresource/DeviceRepoHandler.cpp b/src/hos_cosgi_devicerepository/src/hos/cosgi/service/devicerepository/webresource/DeviceRepoHandler.cpp index 4adc2a72..c0f0d70f 100644 --- a/src/hos_cosgi_devicerepository/src/hos/cosgi/service/devicerepository/webresource/DeviceRepoHandler.cpp +++ b/src/hos_cosgi_devicerepository/src/hos/cosgi/service/devicerepository/webresource/DeviceRepoHandler.cpp @@ -38,39 +38,39 @@ HOS_SERVICE_IMPL_INFO( DeviceRepoHandlerFactory, // Implementation DeviceRepoHandlerFactory::DeviceRepoHandlerFactory(devicerepository::DeviceRepositoryService* repoService) : repoService(repoService) { - infoCategoryFuncs.insert({"id", [](devicerepository::Device* device, const std::string& category)->Variant { + deviceInfoFuncs.add("id", [](Device* device, const std::string& category)->Variant { return device->getDeviceID(); - } }); + }); - infoCategoryFuncs.insert({"type", [](devicerepository::Device* device, const std::string& category)->Variant { + deviceInfoFuncs.add("type", [](Device* device, const std::string& category)->Variant { return device->getDeviceType(); - } }); + }); - infoCategoryFuncs.insert({"status_topic", [](devicerepository::Device* device, const std::string& category)->Variant { + deviceInfoFuncs.add("status_topic", [](Device* device, const std::string& category)->Variant { return device->getStatusTopic(); - } }); + }); - infoCategoryFuncs.insert({"command_topic", [](devicerepository::Device* device, const std::string& category)->Variant { + deviceInfoFuncs.add("command_topic", [](Device* device, const std::string& category)->Variant { return device->getCmdTopic(); - } }); + }); - infoCategoryFuncs.insert({"current_state", [](devicerepository::Device* device, const std::string& category)->Variant { + deviceInfoFuncs.add("current_state", [](Device* device, const std::string& category)->Variant { auto retval = device->getCurrentState(); if (retval.IsMap()) { retval["timestamp"] = utils::timestamp_to_ISO8601(device->getCurrentStateTimestamp()); } return retval; - } }); + }); - infoCategoryFuncs.insert({"last_state", [](devicerepository::Device* device, const std::string& category)->Variant { + deviceInfoFuncs.add("last_state", [](Device* device, const std::string& category)->Variant { auto retval = device->getLastState(); if (retval.IsMap()) { retval["timestamp"] = utils::timestamp_to_ISO8601(device->getLastStateTimestamp()); } return retval; - } }); + }); - infoCategoryFuncs.insert({"uri", [=](devicerepository::Device* device, const std::string& category)->Variant { + deviceInfoFuncs.add("uri", [=](Device* device, const std::string& category)->Variant { std::stringstream ss; /*if (ssl) { ss << "https://"; @@ -80,7 +80,7 @@ DeviceRepoHandlerFactory::DeviceRepoHandlerFactory(devicerepository::DeviceRepos ss << req.getHost() << matchUri.toString() << device->getDeviceID();*/ ss << ""; return ss.str(); - } }); + }); } Net::HTTPRequestHandler* DeviceRepoHandlerFactory::createRequestHandler( Poco::URI matchUri, const Net::HTTPServerRequest& request, bool ssl ) noexcept { @@ -492,26 +492,20 @@ Variant DeviceRepoHandlerFactory::getDeviceInfo(devicerepository::Device* device // We want all info categories if (category.empty()) { - for (auto c : infoCategoryFuncs) { - retval[c.first] = c.second(device, category); - } + deviceInfoFuncs.forEach([&](const std::string& key, const Variant& value){ + retval[key] = value; + }, device, category); // We want a single info category } else { - auto c = infoCategoryFuncs.find(category); - if (c != infoCategoryFuncs.end()) { - retval = c->second(device, category); - if (!path.empty()) { - if (retval.HasPath(path)) { - retval = retval.GetPath(path); - } else { - throw webserver::webresource::WebResourceHandlerException((boost::format("Unknown path \"%1%\" for device info category \"%2%\".") % path % category).str(), - Poco::Net::HTTPResponse::HTTPStatus::HTTP_NOT_FOUND); - } + retval = deviceInfoFuncs.call(category, device, category); + if (!path.empty()) { + if (retval.HasPath(path)) { + retval = retval.GetPath(path); + } else { + throw webserver::webresource::WebResourceHandlerException((boost::format("Unknown path \"%1%\" for device info category \"%2%\".") % path % category).str(), + Poco::Net::HTTPResponse::HTTPStatus::HTTP_NOT_FOUND); } - } else { - throw webserver::webresource::WebResourceHandlerException((boost::format("Unknown device info category \"%1%\"") % category).str(), - Poco::Net::HTTPResponse::HTTPStatus::HTTP_NOT_FOUND); } } diff --git a/src/hos_cosgi_devicerepository/src/hos/cosgi/service/devicerepository/webresource/DeviceRepoHandler.h b/src/hos_cosgi_devicerepository/src/hos/cosgi/service/devicerepository/webresource/DeviceRepoHandler.h index 1bb0ce23..33a41db9 100644 --- a/src/hos_cosgi_devicerepository/src/hos/cosgi/service/devicerepository/webresource/DeviceRepoHandler.h +++ b/src/hos_cosgi_devicerepository/src/hos/cosgi/service/devicerepository/webresource/DeviceRepoHandler.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -80,8 +81,9 @@ class DeviceRepoHandlerFactory public: typedef std::function infoCategoryFunc_t; private: + typedef utils::FunctionTable deviceInfoFuncs_t; DeviceRepositoryService* repoService; - std::map infoCategoryFuncs; + deviceInfoFuncs_t deviceInfoFuncs; public: DeviceRepoHandlerFactory(devicerepository::DeviceRepositoryService* repoService); diff --git a/src/hos_cosgi_ruleengine/include/hos_cosgi_ruleengine/hos/cosgi/service/ruleengine/RuleEngineService.h b/src/hos_cosgi_ruleengine/include/hos_cosgi_ruleengine/hos/cosgi/service/ruleengine/RuleEngineService.h index 7b00e678..8b8bd26c 100644 --- a/src/hos_cosgi_ruleengine/include/hos_cosgi_ruleengine/hos/cosgi/service/ruleengine/RuleEngineService.h +++ b/src/hos_cosgi_ruleengine/include/hos_cosgi_ruleengine/hos/cosgi/service/ruleengine/RuleEngineService.h @@ -22,6 +22,7 @@ namespace service { // forward declarations namespace devicerepository { class DeviceRepositoryService; } namespace core { class CoreService; } +namespace scripting { class ScriptingService; } // service namespace @@ -159,6 +160,12 @@ public: * \return core service. */ virtual core::CoreService* getCoreService() noexcept = 0; + + virtual void registerExecutionBackend(scripting::ScriptingService* service) noexcept = 0; + + virtual scripting::ScriptingService* getExecutionBackend(const std::string& language) noexcept = 0; + + virtual std::vector getExecutionBackends() noexcept = 0; }; diff --git a/src/hos_cosgi_ruleengine/src/BundleActivator.cpp b/src/hos_cosgi_ruleengine/src/BundleActivator.cpp index ab56daff..ac47c8a4 100644 --- a/src/hos_cosgi_ruleengine/src/BundleActivator.cpp +++ b/src/hos_cosgi_ruleengine/src/BundleActivator.cpp @@ -56,7 +56,7 @@ celix_status_t cb_serviceChanged(void* listener, service_event_pt event) { } else if (serviceName && std::strcmp(serviceName, ScriptingService::SERVICE_NAME) == 0) { ScriptingService *service = nullptr; bundleContext_getService(myUserData->bundleContext, event->reference, (void**)&service); - myUserData->serviceImpl->addExecutionBackend(service); + myUserData->serviceImpl->registerExecutionBackend(service); checkReg = true; } diff --git a/src/hos_cosgi_ruleengine/src/hos/cosgi/service/ruleengine/RuleEngineServiceImpl.cpp b/src/hos_cosgi_ruleengine/src/hos/cosgi/service/ruleengine/RuleEngineServiceImpl.cpp index f38ab422..e090e549 100644 --- a/src/hos_cosgi_ruleengine/src/hos/cosgi/service/ruleengine/RuleEngineServiceImpl.cpp +++ b/src/hos_cosgi_ruleengine/src/hos/cosgi/service/ruleengine/RuleEngineServiceImpl.cpp @@ -147,7 +147,7 @@ void RuleEngineServiceImpl::removeRulePkg(const std::string& name) noexcept { } -void RuleEngineServiceImpl::addExecutionBackend(scripting::ScriptingService* service) noexcept { +void RuleEngineServiceImpl::registerExecutionBackend(scripting::ScriptingService* service) noexcept { if (execServices.find(service->getLanguage()) == execServices.end()) { execServices.insert({service->getLanguage(), service}); ROS_INFO_STREAM("RuleEngineService: Added execution service \"" << service->getLanguage() << "\"."); @@ -164,6 +164,15 @@ scripting::ScriptingService* RuleEngineServiceImpl::getExecutionBackend(const st } +std::vector RuleEngineServiceImpl::getExecutionBackends() noexcept { + std::vector retval; + for (auto e : execServices) { + retval.push_back(e.second); + } + return retval; +} + + void RuleEngineServiceImpl::registerRuleConditionFactory(const std::string& type, std::shared_ptr factory) noexcept { condFactories.insert({type, factory}); } diff --git a/src/hos_cosgi_ruleengine/src/hos/cosgi/service/ruleengine/RuleEngineServiceImpl.h b/src/hos_cosgi_ruleengine/src/hos/cosgi/service/ruleengine/RuleEngineServiceImpl.h index f4fd3041..fe3c3665 100644 --- a/src/hos_cosgi_ruleengine/src/hos/cosgi/service/ruleengine/RuleEngineServiceImpl.h +++ b/src/hos_cosgi_ruleengine/src/hos/cosgi/service/ruleengine/RuleEngineServiceImpl.h @@ -123,9 +123,11 @@ public: bool isInitialized() noexcept { return initialized; } - void addExecutionBackend(scripting::ScriptingService* service) noexcept; + virtual void registerExecutionBackend(scripting::ScriptingService* service) noexcept override; - scripting::ScriptingService* getExecutionBackend(const std::string& language) noexcept; + virtual scripting::ScriptingService* getExecutionBackend(const std::string& language) noexcept override; + + virtual std::vector getExecutionBackends() noexcept override; }; diff --git a/src/hos_cosgi_ruleengine/src/hos/cosgi/service/ruleengine/webresource/RuleEngineHandler.cpp b/src/hos_cosgi_ruleengine/src/hos/cosgi/service/ruleengine/webresource/RuleEngineHandler.cpp index f8336d42..fecfbf91 100644 --- a/src/hos_cosgi_ruleengine/src/hos/cosgi/service/ruleengine/webresource/RuleEngineHandler.cpp +++ b/src/hos_cosgi_ruleengine/src/hos/cosgi/service/ruleengine/webresource/RuleEngineHandler.cpp @@ -39,6 +39,10 @@ HOS_SERVICE_IMPL_INFO( RuleEngineHandlerFactory, // Implementation RuleEngineHandlerFactory::RuleEngineHandlerFactory(RuleEngineService* ruleService) : ruleService(ruleService), + engineInfoFuncs([](const std::string& key)->engineInfoFuncs_t::Func_t { + throw webserver::webresource::WebResourceHandlerException((boost::format("Unknown category \"%1%\"") % key).str(), + Poco::Net::HTTPResponse::HTTPStatus::HTTP_NOT_FOUND); + }), pkgInfoFuncs([](const std::string& key)->pkgInfoFuncs_t::Func_t { throw webserver::webresource::WebResourceHandlerException((boost::format("Unknown category \"%1%\"") % key).str(), Poco::Net::HTTPResponse::HTTPStatus::HTTP_NOT_FOUND); @@ -48,6 +52,24 @@ RuleEngineHandlerFactory::RuleEngineHandlerFactory(RuleEngineService* ruleServic Poco::Net::HTTPResponse::HTTPStatus::HTTP_NOT_FOUND); }) { + engineInfoFuncs.add("languages", [](RuleEngineService* engine, const std::string& category)->Variant { + Variant retval = libvariant::Variant::List(); + for (auto e : engine->getExecutionBackends()) { + retval.Append(e->getLanguage()); + } + return retval; + }); + + engineInfoFuncs.add("packages", [this](RuleEngineService* engine, const std::string& category)->Variant { + Variant retval = libvariant::Variant::List(); + for (auto r : engine->getRulePackages()) { + if (!r.expired()) { + retval.Append(getRulePkgInfo(r.lock().get())); + } + } + return retval; + }); + pkgInfoFuncs.add("id", [](rules::RulePackage* pkg, const std::string& category)->Variant { return pkg->getName(); }); @@ -119,6 +141,29 @@ Net::HTTPRequestHandler* RuleEngineHandlerFactory::createRequestHandler( Poco::U } +Variant RuleEngineHandlerFactory::getEngineInfo( RuleEngineService* engine, const std::string& category, const std::string& path ) { + Variant retval; + // We want all info categories + if (category.empty()) { + engineInfoFuncs.forEach([&](const std::string& key, const Variant& value){ + retval[key] = value; + }, engine, category); + + // We want a single info category + } else { + retval = engineInfoFuncs.call(category, engine, category); + if (!path.empty()) { + if (retval.HasPath(path)) { + retval = retval.GetPath(path); + } else { + throw webserver::webresource::WebResourceHandlerException((boost::format("Unknown path \"%1%\" for rule package info category \"%2%\".") % path % category).str(), + Poco::Net::HTTPResponse::HTTPStatus::HTTP_NOT_FOUND); + } + } + } + return retval; +} + Variant RuleEngineHandlerFactory::getRulePkgInfo( rules::RulePackage* pkg, const std::string& category, const std::string& path ) { Variant retval; @@ -214,9 +259,11 @@ void RuleEngineHandler::__handleInfo(Poco::Net::HTTPServerRequest &req, Poco::Ne form.reset(new Net::HTMLForm(req)); } - // Nothing given, query mode (there is no real query functionality implemented yet though) + // Nothing given, return engine info if (pathPieces.size() <= matchPieces.size()) { - auto pkgs = ruleService->getRulePackages(); + handleResponse(req, resp, parent->getEngineInfo(ruleService, "", "")); + + /*auto pkgs = ruleService->getRulePackages(); // Parse HTTP header "Range" parameter (to support dojo/store) size_t rangeStart = 0; @@ -270,7 +317,7 @@ void RuleEngineHandler::__handleInfo(Poco::Net::HTTPServerRequest &req, Poco::Ne resp.set("Content-Range", rangeOut); resp.set("X-Content-Range", rangeOut); handleResponse(req, resp, result); - } + }*/ // rule package given } else if (pathPieces.size() == matchPieces.size() + 1) { diff --git a/src/hos_cosgi_ruleengine/src/hos/cosgi/service/ruleengine/webresource/RuleEngineHandler.h b/src/hos_cosgi_ruleengine/src/hos/cosgi/service/ruleengine/webresource/RuleEngineHandler.h index 078e748f..cee52ff9 100644 --- a/src/hos_cosgi_ruleengine/src/hos/cosgi/service/ruleengine/webresource/RuleEngineHandler.h +++ b/src/hos_cosgi_ruleengine/src/hos/cosgi/service/ruleengine/webresource/RuleEngineHandler.h @@ -78,13 +78,12 @@ public: class RuleEngineHandlerFactory : public webserver::webresource::WebResourceHandlerFactoryImpl { -public: - typedef std::function pkgInfoFunc_t; - typedef std::function ruleInfoFuncFunc_t; private: + typedef utils::FunctionTable engineInfoFuncs_t; typedef utils::FunctionTable pkgInfoFuncs_t; typedef utils::FunctionTable ruleInfoFuncs_t; RuleEngineService* ruleService; + engineInfoFuncs_t engineInfoFuncs; pkgInfoFuncs_t pkgInfoFuncs; ruleInfoFuncs_t ruleInfoFuncs; @@ -93,6 +92,8 @@ public: virtual Poco::Net::HTTPRequestHandler* createRequestHandler(Poco::URI matchUri, const Poco::Net::HTTPServerRequest& request, bool ssl ) noexcept override; + libvariant::Variant getEngineInfo( RuleEngineService* engine, const std::string& category = "", const std::string& path = "" ); + libvariant::Variant getRulePkgInfo( rules::RulePackage* pkg, const std::string& category = "", const std::string& path = "" ); libvariant::Variant getRuleInfo( rules::Rule* pkg, const std::string& category = "", const std::string& path = "" ); diff --git a/src/hos_cosgi_webserver/include/hos_cosgi_webserver/hos/cosgi/service/webserver/webresource/WebResourceHandlerImpl.h b/src/hos_cosgi_webserver/include/hos_cosgi_webserver/hos/cosgi/service/webserver/webresource/WebResourceHandlerImpl.h index 4512f18a..5324e6c0 100644 --- a/src/hos_cosgi_webserver/include/hos_cosgi_webserver/hos/cosgi/service/webserver/webresource/WebResourceHandlerImpl.h +++ b/src/hos_cosgi_webserver/include/hos_cosgi_webserver/hos/cosgi/service/webserver/webresource/WebResourceHandlerImpl.h @@ -692,7 +692,6 @@ protected: } handleResponse(req, resp, msg); } - };