From 0a63e3752c1fcd8ca5b429c0ae3b241279033126 Mon Sep 17 00:00:00 2001 From: matzman Date: Thu, 11 Jun 2015 19:08:09 +0200 Subject: [PATCH] . --- .../webresource/DeviceRepoHandler.cpp | 2 +- .../webresource/RuleEngineHandler.cpp | 200 +++++++++++++++--- .../webresource/RuleEngineHandler.h | 12 +- .../webroot/libs/hos/RuleEngine.js | 14 +- .../libs/hos/stores/DeviceRepoStore.js | 29 --- src/hos_cosgi_testwebapp/webroot/rule01.html | 2 +- 6 files changed, 187 insertions(+), 72 deletions(-) delete mode 100644 src/hos_cosgi_testwebapp/webroot/libs/hos/stores/DeviceRepoStore.js 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 6ce50dfa..49ad42b3 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 @@ -136,7 +136,7 @@ void DeviceRepoHandler::__handleInfo(Poco::Net::HTTPServerRequest &req, Poco::Ne // Iterate over devices Variant result = Variant::List(); - if (devices.size() > 0) { + if (devices.size() > rangeStart) { for (size_t t = rangeStart; t <= rangeStop; t++) { auto dev = devices[t].lock(); result.Append(parent->getDeviceInfo(dev.get())); 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 6e886ce6..80d7dc2c 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 @@ -52,11 +52,11 @@ RuleEngineHandlerFactory::RuleEngineHandlerFactory(RuleEngineService* ruleServic Poco::Net::HTTPResponse::HTTPStatus::HTTP_NOT_FOUND); }) { - engineInfoFuncs.add("id", [](RuleEngineService* engine, const std::string& category)->Variant { + engineInfoFuncs.add("id", [](Poco::Net::HTTPServerRequest& req, Poco::Net::HTMLForm& form, RuleEngineService* engine, const std::string& category)->Variant { return engine->getName(); }); - engineInfoFuncs.add("languages", [](RuleEngineService* engine, const std::string& category)->Variant { + engineInfoFuncs.add("languages", [](Poco::Net::HTTPServerRequest& req, Poco::Net::HTMLForm& form, RuleEngineService* engine, const std::string& category)->Variant { Variant retval = libvariant::Variant::List(); for (auto e : engine->getExecutionBackends()) { retval.Append(e->getLanguage()); @@ -64,33 +64,38 @@ RuleEngineHandlerFactory::RuleEngineHandlerFactory(RuleEngineService* ruleServic return retval; }); - engineInfoFuncs.add("packages", [this](RuleEngineService* engine, const std::string& category)->Variant { + engineInfoFuncs.add("packages", [this](Poco::Net::HTTPServerRequest& req, Poco::Net::HTMLForm& form, RuleEngineService* engine, const std::string& category)->Variant { + bool onlyIds = form.has("onlyids"); Variant retval = libvariant::Variant::List(); for (auto r : engine->getRulePackages()) { if (!r.expired()) { - retval.Append(getRulePkgInfo(r.lock().get())); + if (onlyIds) { + retval.Append(r.lock()->getName()); + } else { + retval.Append(getRulePkgInfo(req, form, r.lock().get())); + } } } return retval; }); - pkgInfoFuncs.add("id", [](rules::RulePackage* pkg, const std::string& category)->Variant { + pkgInfoFuncs.add("id", [](Poco::Net::HTTPServerRequest& req, Poco::Net::HTMLForm& form, rules::RulePackage* pkg, const std::string& category)->Variant { return pkg->getName(); }); - pkgInfoFuncs.add("parent", [](rules::RulePackage* pkg, const std::string& category)->Variant { + pkgInfoFuncs.add("parent", [](Poco::Net::HTTPServerRequest& req, Poco::Net::HTMLForm& form, rules::RulePackage* pkg, const std::string& category)->Variant { return pkg->getParent()->getName(); }); - pkgInfoFuncs.add("language", [](rules::RulePackage* pkg, const std::string& category)->Variant { + pkgInfoFuncs.add("language", [](Poco::Net::HTTPServerRequest& req, Poco::Net::HTMLForm& form, rules::RulePackage* pkg, const std::string& category)->Variant { return pkg->getLanguage(); }); - pkgInfoFuncs.add("enabled", [](rules::RulePackage* pkg, const std::string& category)->Variant { + pkgInfoFuncs.add("enabled", [](Poco::Net::HTTPServerRequest& req, Poco::Net::HTMLForm& form, rules::RulePackage* pkg, const std::string& category)->Variant { return pkg->isEnabled(); }); - pkgInfoFuncs.add("globalcontext", [](rules::RulePackage* pkg, const std::string& category)->Variant { + pkgInfoFuncs.add("globalcontext", [](Poco::Net::HTTPServerRequest& req, Poco::Net::HTMLForm& form, rules::RulePackage* pkg, const std::string& category)->Variant { auto gc = pkg->getGlobalScriptContext(); if (!gc.expired()) { return gc.lock()->getJSONRepresentation(); @@ -99,30 +104,39 @@ RuleEngineHandlerFactory::RuleEngineHandlerFactory(RuleEngineService* ruleServic } }); - pkgInfoFuncs.add("rules", [this](rules::RulePackage* pkg, const std::string& category)->Variant { + pkgInfoFuncs.add("rules", [this](Poco::Net::HTTPServerRequest& req, Poco::Net::HTMLForm& form, rules::RulePackage* pkg, const std::string& category)->Variant { + bool onlyIds = form.has("onlyids"); Variant retval = libvariant::Variant::List(); for (auto r : pkg->getRules()) { if (!r.expired()) { - retval.Append(getRuleInfo(r.lock().get())); + if (onlyIds) { + retval.Append(r.lock()->getName()); + } else { + retval.Append(getRuleInfo(req, form, r.lock().get())); + } } } return retval; }); - ruleInfoFuncs.add("id", [](rules::Rule* rule, const std::string& category)->Variant { + ruleInfoFuncs.add("id", [](Poco::Net::HTTPServerRequest& req, Poco::Net::HTMLForm& form, rules::Rule* rule, const std::string& category)->Variant { return rule->getName(); }); - ruleInfoFuncs.add("parent", [](rules::Rule* rule, const std::string& category)->Variant { + ruleInfoFuncs.add("parent", [](Poco::Net::HTTPServerRequest& req, Poco::Net::HTMLForm& form, rules::Rule* rule, const std::string& category)->Variant { return rule->getParent()->getName(); }); - ruleInfoFuncs.add("enabled", [](rules::Rule* rule, const std::string& category)->Variant { + ruleInfoFuncs.add("enabled", [](Poco::Net::HTTPServerRequest& req, Poco::Net::HTMLForm& form, rules::Rule* rule, const std::string& category)->Variant { return rule->isEnabled(); }); - ruleInfoFuncs.add("script", [](rules::Rule* rule, const std::string& category)->Variant { + ruleInfoFuncs.add("active", [](Poco::Net::HTTPServerRequest& req, Poco::Net::HTMLForm& form, rules::Rule* rule, const std::string& category)->Variant { + return rule->isActive(); + }); + + ruleInfoFuncs.add("script", [](Poco::Net::HTTPServerRequest& req, Poco::Net::HTMLForm& form, rules::Rule* rule, const std::string& category)->Variant { auto script = rule->getScript(); if (script) { return script->getJSONRepresentation(); @@ -131,7 +145,7 @@ RuleEngineHandlerFactory::RuleEngineHandlerFactory(RuleEngineService* ruleServic } }); - ruleInfoFuncs.add("exitscript", [](rules::Rule* rule, const std::string& category)->Variant { + ruleInfoFuncs.add("exitscript", [](Poco::Net::HTTPServerRequest& req, Poco::Net::HTMLForm& form, rules::Rule* rule, const std::string& category)->Variant { auto script = rule->getExitScript(); if (script) { return script->getJSONRepresentation(); @@ -140,7 +154,7 @@ RuleEngineHandlerFactory::RuleEngineHandlerFactory(RuleEngineService* ruleServic } }); - ruleInfoFuncs.add("condition", [](rules::Rule* rule, const std::string& category)->Variant { + ruleInfoFuncs.add("condition", [](Poco::Net::HTTPServerRequest& req, Poco::Net::HTMLForm& form, rules::Rule* rule, const std::string& category)->Variant { return rule->getConditionJSONRepresentation(); }); @@ -153,17 +167,17 @@ Net::HTTPRequestHandler* RuleEngineHandlerFactory::createRequestHandler( Poco::U } -Variant RuleEngineHandlerFactory::getEngineInfo( RuleEngineService* engine, const std::string& category, const std::string& path ) { +Variant RuleEngineHandlerFactory::getEngineInfo( Net::HTTPServerRequest& req, Net::HTMLForm& form, 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); + }, req, form, engine, category); // We want a single info category } else { - retval = engineInfoFuncs.call(category, engine, category); + retval = engineInfoFuncs.call(category, req, form, engine, category); if (!path.empty()) { if (retval.HasPath(path)) { retval = retval.GetPath(path); @@ -177,17 +191,17 @@ Variant RuleEngineHandlerFactory::getEngineInfo( RuleEngineService* engine, cons } -Variant RuleEngineHandlerFactory::getRulePkgInfo( rules::RulePackage* pkg, const std::string& category, const std::string& path ) { +Variant RuleEngineHandlerFactory::getRulePkgInfo( Net::HTTPServerRequest& req, Net::HTMLForm& form, rules::RulePackage* pkg, const std::string& category, const std::string& path ) { Variant retval; // We want all info categories if (category.empty()) { pkgInfoFuncs.forEach([&](const std::string& key, const Variant& value){ retval[key] = value; - }, pkg, category); + }, req, form, pkg, category); // We want a single info category } else { - retval = pkgInfoFuncs.call(category, pkg, category); + retval = pkgInfoFuncs.call(category, req, form, pkg, category); if (!path.empty()) { if (retval.HasPath(path)) { retval = retval.GetPath(path); @@ -202,17 +216,17 @@ Variant RuleEngineHandlerFactory::getRulePkgInfo( rules::RulePackage* pkg, const -Variant RuleEngineHandlerFactory::getRuleInfo( rules::Rule* rule, const std::string& category, const std::string& path ) { +Variant RuleEngineHandlerFactory::getRuleInfo( Net::HTTPServerRequest& req, Net::HTMLForm& form, rules::Rule* rule, const std::string& category, const std::string& path ) { Variant retval; // We want all info categories if (category.empty()) { ruleInfoFuncs.forEach([&](const std::string& key, const Variant& value){ retval[key] = value; - }, rule, category); + }, req, form, rule, category); // We want a single info category } else { - retval = ruleInfoFuncs.call(category, rule, category); + retval = ruleInfoFuncs.call(category, req, form, rule, category); if (!path.empty()) { if (retval.HasPath(path)) { retval = retval.GetPath(path); @@ -267,14 +281,136 @@ void RuleEngineHandler::__handleInfo(Poco::Net::HTTPServerRequest &req, Poco::Ne // Nothing given, return engine info if (pathPieces.size() <= matchPieces.size()) { - handleResponse(req, resp, form, parent->getEngineInfo(ruleService, "", "")); + handleResponse(req, resp, form, parent->getEngineInfo(req, form, ruleService, "", "")); - // rule package given - } else if (pathPieces.size() == matchPieces.size() + 1) { - - // rule given - } else if (pathPieces.size() == matchPieces.size() + 2) { + } else { + std::weak_ptr rule; + std::string firstPiece = pathPieces[matchPieces.size()]; + bool alreadyHandled = false; + size_t pathStart = 0; + Variant retval; + if (firstPiece == "packages") { + if (pathPieces.size() <= matchPieces.size() + 1) { + auto pkgs = ruleService->getRulePackages(); + // Range header parameter + size_t rangeStart = 0; + size_t rangeStop = pkgs.size() - 1; + getRangeHeaderParameter(req, rangeStart, rangeStop, rangeStop); + // Iterate over devices + retval = Variant::List(); + if (pkgs.size() > rangeStart) { + for (size_t t = rangeStart; t <= rangeStop; t++) { + auto dev = pkgs[t].lock(); + retval.Append(parent->getRulePkgInfo(req, form, dev.get())); + } + } + // There are no devices and a range was given, probably out of range + if (retval.Size() == 0 && rangeStart > 0) { + if (rangeStart > 0) { + handleErrorResponse(req, resp, form, "Out of range", Poco::Net::HTTPResponse::HTTP_NOT_FOUND); + } else { + handleResponse(req, resp, form, retval); + } + // Return devices array + } else { + setRangeHeaderParameter(resp, rangeStart, rangeStop, pkgs.size()); + handleResponse(req, resp, form, retval); + } + alreadyHandled = true; + } else { + // Get rule package + std::string pkgid = pathPieces[matchPieces.size()+1]; + auto pkg = ruleService->getRulePackage(pkgid); + if (!pkg.expired()) { + // Get info category + std::string category; + pathStart = 5; + if (pathPieces.size() > matchPieces.size() + 2) { + category = pathPieces[matchPieces.size() + 2]; + pathStart = 6; + } + if (category == "rules") { + if (pathPieces.size() <= matchPieces.size() + 3) { + auto rules = pkg.lock()->getRules(); + // Range header parameter + size_t rangeStart = 0; + size_t rangeStop = rules.size() - 1; + getRangeHeaderParameter(req, rangeStart, rangeStop, rangeStop); + // Iterate over devices + retval = Variant::List(); + if (rules.size() > rangeStart) { + for (size_t t = rangeStart; t <= rangeStop; t++) { + auto r = rules[t].lock(); + retval.Append(parent->getRuleInfo(req, form, r.get())); + } + } + // There are no devices and a range was given, probably out of range + if (retval.Size() == 0 && rangeStart > 0) { + if (rangeStart > 0) { + handleErrorResponse(req, resp, form, "Out of range", Poco::Net::HTTPResponse::HTTP_NOT_FOUND); + } else { + handleResponse(req, resp, form, retval); + } + // Return devices array + } else { + setRangeHeaderParameter(resp, rangeStart, rangeStop, rules.size()); + handleResponse(req, resp, form, retval); + } + alreadyHandled = true; + } else { + // Get rule + std::string ruleid = pathPieces[matchPieces.size()+3]; + auto rule = pkg.lock()->getRule(ruleid); + if (!rule.expired()) { + // Get info category + std::string category; + pathStart = 7; + if (pathPieces.size() > matchPieces.size() + 4) { + category = pathPieces[matchPieces.size() + 4]; + pathStart = 8; + } + retval = parent->getRuleInfo(req, form, rule.lock().get(), category); + } else { + throw webserver::webresource::WebResourceHandlerException((boost::format("Could not find rule \"%1%\"") % ruleid).str(), + Poco::Net::HTTPResponse::HTTPStatus::HTTP_NOT_FOUND); + } + } + } else { + retval = parent->getRulePkgInfo(req, form, pkg.lock().get(), category); + } + } else { + throw webserver::webresource::WebResourceHandlerException((boost::format("Could not find rule package \"%1%\"") % pkgid).str(), + Poco::Net::HTTPResponse::HTTPStatus::HTTP_NOT_FOUND); + } + } + } else { + retval = parent->getEngineInfo(req, form, ruleService, firstPiece, ""); + } + if (!alreadyHandled) { + // Get path from url and append pointer parameter + std::stringstream pathstream; + for (int i = pathStart; i < pathPieces.size(); i++) { + pathstream << "/" << pathPieces[i]; + } + std::string pointer; + if (getPointerParameter(pointer, form)) { + if (pointer.size() > 0 && pointer[0] != '/') { + pathstream << "/"; + } + pathstream << pointer; + } + auto path = pathstream.str(); + if (!path.empty()) { + if (retval.HasPath(path)) { + retval = retval.GetPath(path); + } else { + throw webserver::webresource::WebResourceHandlerException((boost::format("Unknown path \"%1%\".") % path).str(), + Poco::Net::HTTPResponse::HTTPStatus::HTTP_NOT_FOUND); + } + } + handleResponse(req, resp, form, retval); + } } } 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 321a84ae..bd37146f 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 @@ -79,9 +79,9 @@ public: class RuleEngineHandlerFactory : public webserver::webresource::WebResourceHandlerFactoryImpl { private: - typedef utils::FunctionTable engineInfoFuncs_t; - typedef utils::FunctionTable pkgInfoFuncs_t; - typedef utils::FunctionTable ruleInfoFuncs_t; + typedef utils::FunctionTable engineInfoFuncs_t; + typedef utils::FunctionTable pkgInfoFuncs_t; + typedef utils::FunctionTable ruleInfoFuncs_t; RuleEngineService* ruleService; engineInfoFuncs_t engineInfoFuncs; pkgInfoFuncs_t pkgInfoFuncs; @@ -92,11 +92,11 @@ 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 getEngineInfo( Poco::Net::HTTPServerRequest& req, Poco::Net::HTMLForm& form, 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 getRulePkgInfo( Poco::Net::HTTPServerRequest& req, Poco::Net::HTMLForm& form, 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 = "" ); + libvariant::Variant getRuleInfo( Poco::Net::HTTPServerRequest& req, Poco::Net::HTMLForm& form, rules::Rule* pkg, const std::string& category = "", const std::string& path = "" ); }; diff --git a/src/hos_cosgi_testwebapp/webroot/libs/hos/RuleEngine.js b/src/hos_cosgi_testwebapp/webroot/libs/hos/RuleEngine.js index 42f3dac2..c8db1a2c 100644 --- a/src/hos_cosgi_testwebapp/webroot/libs/hos/RuleEngine.js +++ b/src/hos_cosgi_testwebapp/webroot/libs/hos/RuleEngine.js @@ -6,12 +6,20 @@ define([ 'dstore/SimpleQuery', 'dstore/Trackable', 'dstore/Tree', - "dojox/socket", - "dojo/_base/xhr", + "hos/Socket", + "dojo/request/xhr", "dojox/uuid/generateRandomUuid" ], function(config, declare, Rest, RequestMemory, SimpleQuery, Trackable, Tree, Socket, xhr, generateRandomUuid){ - var RuleEngineStore = declare([Rest, RequestMemory, SimpleQuery, Trackable, Tree]); + var RuleEngineStore = declare([Rest, RequestMemory, SimpleQuery, Trackable, Tree], { + _getTarget: function(id){ + var target = this.target; + if(!target.slice(-1) == '/'){ + target += "/"; + } + return target + "packages" + id; + } + }); var _store = new RuleEngineStore({ target: config.hos.ruleEngineUrl diff --git a/src/hos_cosgi_testwebapp/webroot/libs/hos/stores/DeviceRepoStore.js b/src/hos_cosgi_testwebapp/webroot/libs/hos/stores/DeviceRepoStore.js deleted file mode 100644 index 63341b4b..00000000 --- a/src/hos_cosgi_testwebapp/webroot/libs/hos/stores/DeviceRepoStore.js +++ /dev/null @@ -1,29 +0,0 @@ -define([ - 'dojo/_base/declare', - 'dstore/Rest', - 'dstore/RequestMemory', - 'dstore/SimpleQuery', - 'dstore/Trackable', - 'hos/Socket', - 'dojo/_base/xhr', - 'dojox/uuid/generateRandomUuid' -], function(declare, Rest, RequestMemory, SimpleQuery, Trackable, Socket, xhr, generateRandomUuid){ - - return declare([Rest, RequestMemory, SimpleQuery, Trackable], { - - sendDeviceCommand: function(id, cmd) { - console.log("ToDo: send command", cmd ,"to " + id); - var devurl = config.hos.deviceRepoUrl + "/" + id + "?method=command&value=" + encodeURIComponent(JSON.stringify(cmd)); - xhr.get({url: devurl}).then(function(data){ - // Do something with the handled data - }, function(err){ - // Handle the error condition - }, function(evt){ - // Handle a progress event from the request if the - // browser supports XHR2 - }); - }; - - }); - -}); diff --git a/src/hos_cosgi_testwebapp/webroot/rule01.html b/src/hos_cosgi_testwebapp/webroot/rule01.html index 7d591714..88a336c3 100644 --- a/src/hos_cosgi_testwebapp/webroot/rule01.html +++ b/src/hos_cosgi_testwebapp/webroot/rule01.html @@ -41,7 +41,7 @@ "dojo/on", "dojo/domReady!" ], function(RuleEngine, domConstruct, dom, on){ - var test1 = RuleEngine.get("myid/bla"); + var test1 = RuleEngine.get("rulepkg01"); console.log("test1: ", test1); var test2 = RuleEngine.filter({arg01: "param01"}); console.log("test2: ", test2);