diff --git a/src/hos_cosgi_core/include/hos_cosgi_core/hos/cosgi/service/Implementation.h b/src/hos_cosgi_core/include/hos_cosgi_core/hos/cosgi/service/Implementation.h index c59a78e6..c631a9f4 100644 --- a/src/hos_cosgi_core/include/hos_cosgi_core/hos/cosgi/service/Implementation.h +++ b/src/hos_cosgi_core/include/hos_cosgi_core/hos/cosgi/service/Implementation.h @@ -324,7 +324,7 @@ public: * \param[in] e event. * \return notified observer count. */ - size_t notifyObservers(const _Key& k, const _Event* e) noexcept override { + virtual size_t notifyObservers(const _Key& k, const _Event* e) noexcept override { std::lock_guard lock(_observersMutex); size_t retval = 0; // We work with a copy so that we can insert/remove observers within a callback. @@ -337,6 +337,27 @@ public: return retval; } + /** + * Notify observers of a new event. + * + * \param[in] key observer filter key. + * \param[in] substkey key that is send to the observers. + * \param[in] e event. + * \return notified observer count. + */ + virtual size_t notifyObservers(const _Key& key, const _Key& substkey, const _Event* e) noexcept override { + std::lock_guard lock(_observersMutex); + size_t retval = 0; + // We work with a copy so that we can insert/remove observers within a callback. + observers_type tmp = _observers; + auto ol = tmp.equal_range(key); + for (auto i = ol.first; i != ol.second; i++) { + i->second->notificationReceived(this, substkey, e); + retval++; + } + return retval; + } + }; diff --git a/src/hos_cosgi_core/include/hos_cosgi_core/hos/cosgi/service/Interface.h b/src/hos_cosgi_core/include/hos_cosgi_core/hos/cosgi/service/Interface.h index 463e047c..26f647fe 100644 --- a/src/hos_cosgi_core/include/hos_cosgi_core/hos/cosgi/service/Interface.h +++ b/src/hos_cosgi_core/include/hos_cosgi_core/hos/cosgi/service/Interface.h @@ -269,6 +269,18 @@ public: */ virtual size_t notifyObservers(const _Key& key, const _Event* e) noexcept = 0; + /** + * Notify observers of a new event. + * + * The purpose of this function is to implement an all-events key. + * + * \param[in] key observer filter key. + * \param[in] substkey key that is send to the observers. + * \param[in] e event. + * \return notified observer count. + */ + virtual size_t notifyObservers(const _Key& key, const _Key& substkey, const _Event* e) noexcept = 0; + }; diff --git a/src/hos_cosgi_devicerepository/include/hos_cosgi_devicerepository/hos/cosgi/service/devicerepository/DeviceRepositoryService.h b/src/hos_cosgi_devicerepository/include/hos_cosgi_devicerepository/hos/cosgi/service/devicerepository/DeviceRepositoryService.h index ae573c3c..0b1ae91c 100644 --- a/src/hos_cosgi_devicerepository/include/hos_cosgi_devicerepository/hos/cosgi/service/devicerepository/DeviceRepositoryService.h +++ b/src/hos_cosgi_devicerepository/include/hos_cosgi_devicerepository/hos/cosgi/service/devicerepository/DeviceRepositoryService.h @@ -38,7 +38,8 @@ enum class DeviceEventType : int { DEVICE_REMOVED = 2, STATUS_UPDATE_RECEIVED = 3, COMMAND_RECEIVED = 4, - STATE_CHANGED = 5 + STATE_CHANGED = 5, + ALL_EVENTS = 6 }; diff --git a/src/hos_cosgi_devicerepository/src/hos/cosgi/service/devicerepository/DeviceRepositoryServiceImpl.cpp b/src/hos_cosgi_devicerepository/src/hos/cosgi/service/devicerepository/DeviceRepositoryServiceImpl.cpp index 651bb5ca..9cc8f44b 100644 --- a/src/hos_cosgi_devicerepository/src/hos/cosgi/service/devicerepository/DeviceRepositoryServiceImpl.cpp +++ b/src/hos_cosgi_devicerepository/src/hos/cosgi/service/devicerepository/DeviceRepositoryServiceImpl.cpp @@ -40,10 +40,12 @@ bool DeviceImpl::handleStatusMsg(const Variant& msg, const timestamp_t& stamp) n DeviceStatusMsgEvent event(this, msg, stamp); notifyObservers(DeviceEventType::STATUS_UPDATE_RECEIVED, &event); + notifyObservers(DeviceEventType::ALL_EVENTS, DeviceEventType::STATUS_UPDATE_RECEIVED, &event); if (stateChanged){ DeviceStateChangeEvent event(this, msg, stamp); notifyObservers(DeviceEventType::STATE_CHANGED, &event); + notifyObservers(DeviceEventType::ALL_EVENTS, DeviceEventType::STATE_CHANGED, &event); } return stateChanged; @@ -54,6 +56,7 @@ void DeviceImpl::handleCommandMsg(const Variant& msg, const timestamp_t& stamp) std::lock_guard lock(objMutex); DeviceCmdMsgEvent event(this, msg, stamp); notifyObservers(DeviceEventType::COMMAND_RECEIVED, &event); + notifyObservers(DeviceEventType::ALL_EVENTS, DeviceEventType::COMMAND_RECEIVED, &event); } @@ -173,6 +176,7 @@ void DeviceRepositoryServiceImpl::addDevice(const std::string& name, XmlRpc::Xml // send device added event DeviceAddedEvent event(dev.get(), std::chrono::system_clock::now()); notifyObservers(DeviceEventType::DEVICE_ADDED, &event); + notifyObservers(DeviceEventType::ALL_EVENTS, DeviceEventType::DEVICE_ADDED, &event); } @@ -182,7 +186,9 @@ void DeviceRepositoryServiceImpl::removeDevice(const std::string& name) { if (dev != devices.end()) { DeviceRemovedEvent event(dev->second.get(), std::chrono::system_clock::now()); notifyObservers(DeviceEventType::DEVICE_REMOVED, &event); + notifyObservers(DeviceEventType::ALL_EVENTS, DeviceEventType::DEVICE_REMOVED, &event); dev->second->notifyObservers(DeviceEventType::DEVICE_REMOVED, &event); + dev->second->notifyObservers(DeviceEventType::ALL_EVENTS, DeviceEventType::DEVICE_REMOVED, &event); devices.erase(name); } } @@ -232,7 +238,15 @@ void DeviceRepositoryServiceImpl::statusMsgCallback(const hos_core_msgs::DeviceS auto dev = devices.find(msg->device_id); if (dev != devices.end()) { auto stamp = std::chrono::system_clock::now(); - dev->second->handleStatusMsg(m, stamp); + bool stateChanged = dev->second->handleStatusMsg(m, stamp); + DeviceStatusMsgEvent event(dev->second.get(), m, stamp); + notifyObservers(DeviceEventType::STATUS_UPDATE_RECEIVED, &event); + notifyObservers(DeviceEventType::ALL_EVENTS, DeviceEventType::STATUS_UPDATE_RECEIVED, &event); + if (stateChanged) { + DeviceStateChangeEvent event(dev->second.get(), m, stamp); + notifyObservers(DeviceEventType::STATE_CHANGED, &event); + notifyObservers(DeviceEventType::ALL_EVENTS, DeviceEventType::STATE_CHANGED, &event); + } } } else { @@ -261,6 +275,9 @@ void DeviceRepositoryServiceImpl::cmdMsgCallback(const hos_core_msgs::DeviceComm if (dev != devices.end()) { auto stamp = std::chrono::system_clock::now(); dev->second->handleCommandMsg(m, stamp); + DeviceCmdMsgEvent event(dev->second.get(), m, stamp); + notifyObservers(DeviceEventType::COMMAND_RECEIVED, &event); + notifyObservers(DeviceEventType::ALL_EVENTS, DeviceEventType::COMMAND_RECEIVED, &event); } } else { 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 8574759a..fad3a429 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 @@ -77,39 +77,103 @@ DeviceAPIMethod DeviceRepoHandlerFactory::getDeviceAPIMethod() noexcept { } + +std::shared_ptr DeviceRepoHandlerFactory::getDeviceEventQueue(std::string clientID) { + if (clientID.empty()) { + + } else { + + } +} + + Net::HTTPRequestHandler* DeviceRepoHandlerFactory::createRequestHandler( Poco::URI matchUri, const Net::HTTPServerRequest& request, bool ssl ) noexcept { - return new DeviceRepoHandler(matchUri, repoService, infoCategoryFuncs, ssl); + if(request.find("Upgrade") != request.end() && Poco::icompare(request["Upgrade"], "websocket") == 0) + return new DeviceRepoEventWebSocketHandler(matchUri, repoService, infoCategoryFuncs, ssl); + else { + DeviceAPIMethod method = getDeviceAPIMethod(); + if (method == DeviceAPIMethod::REGISTEREVENT) { + return new DeviceRepoEventLongPollingHandler(matchUri, repoService, infoCategoryFuncs, ssl); + } else { + return new DeviceRepoInfoHandler(matchUri, method, repoService, infoCategoryFuncs, ssl); + } + } } -void DeviceRepoHandler::_handleGET(Poco::Net::HTTPServerRequest &req, Poco::Net::HTTPServerResponse &resp) { - // Get API method parameter - Net::HTMLForm form(req); - DeviceAPIMethod dataMethod = DeviceAPIMethod::GET; // Default method is get - std::string methodValue; - if (form.has("method")) { - std::string methodRaw = form.get("method"); - bool requireValue = false; - if (methodRaw == "get") { - // do nothing - } else if (methodRaw == "command") { - dataMethod = DeviceAPIMethod::COMMAND; - requireValue = true; - } else if (methodRaw.compare("statusupdate") == 0) { - dataMethod = DeviceAPIMethod::STATUSUPDATE; - requireValue = true; - } else { - throw webserver::webresource::WebResourceHandlerException((boost::format("Unknown API method \"%1%\"") % methodRaw).str(), - Poco::Net::HTTPResponse::HTTPStatus::HTTP_BAD_REQUEST); + + + + +Variant DeviceRepoHandlerBase::getDeviceInfo(devicerepository::Device* device, Net::HTTPServerRequest &req, const std::string& category, const std::vector& path) { + Variant retval; + + // We want all info categories + if (category.empty()) { + for (auto c : infoCategoryFuncs) { + retval[c.first] = c.second(matchUri, device, req, category, ssl); } - if (requireValue) { - if (form.has("value")) { - methodValue = form.get("value"); - } else { - throw webserver::webresource::WebResourceHandlerException((boost::format("API method \"%1%\" requires a value parameter.") % methodRaw).str(), - Poco::Net::HTTPResponse::HTTPStatus::HTTP_BAD_REQUEST); + + // We want a single info category + } else { + auto c = infoCategoryFuncs.find(category); + if (c != infoCategoryFuncs.end()) { + retval = c->second(matchUri, device, req, category, ssl); + if (path.size() > 0) { + std::stringstream ss; + for (auto p : path) { + ss << "/" << p; + } + std::string pathstr = ss.str(); + if (retval.HasPath(pathstr)) { + retval = retval.GetPath(pathstr); + } else { + throw webserver::webresource::WebResourceHandlerException((boost::format("Unknown path \"%1%\" for device info category \"%2%\".") % pathstr % 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); + } + } + + return retval; +} + + + +void DeviceRepoHandlerBase::sendDeviceCommand(devicerepository::Device* device, Net::HTTPServerRequest &req, const std::string& cmd, const std::vector& path) { + Variant cmdMsg; + VariantRef mPart = cmdMsg.Ref(); + if (path.size() > 0) { + for (int i = 0; i < path.size(); i++) { + mPart[path[i]] = Variant(); + mPart.ReassignRef(mPart[path[i]]); + } + } + /* + * The libvariant json deserializer knows nothing about RFC 7159, therefore non-object or non-array values are rejected. + * As a workaround we use the yaml deserializer (yaml can be considered a super-set of json). + * Fun fact: the json serializer accepts non-object or non-array values. + */ + //mPart = DeserializeJSON(cmd); + mPart = DeserializeYAML(cmd); + device->sendCommand(cmdMsg); +} + + + +void DeviceRepoInfoHandler::__handle(Poco::Net::HTTPServerRequest &req, Poco::Net::HTTPServerResponse &resp, Net::HTMLForm& form) { + + std::string methodValue; + if (method == DeviceAPIMethod::COMMAND || method == DeviceAPIMethod::STATUSUPDATE) { + if (form.has("value")) { + methodValue = form.get("value"); + } else { + throw webserver::webresource::WebResourceHandlerException("API method requires a value parameter.", + Poco::Net::HTTPResponse::HTTPStatus::HTTP_BAD_REQUEST); } } @@ -120,7 +184,7 @@ void DeviceRepoHandler::_handleGET(Poco::Net::HTTPServerRequest &req, Poco::Net: // No device given if (pathPieces.size() <= matchPieces.size()) { - if (dataMethod != DeviceAPIMethod::GET) { + if (method != DeviceAPIMethod::GET) { throw webserver::webresource::WebResourceHandlerException("Requested API method requires a device", Poco::Net::HTTPResponse::HTTPStatus::HTTP_BAD_REQUEST); } @@ -181,7 +245,7 @@ void DeviceRepoHandler::_handleGET(Poco::Net::HTTPServerRequest &req, Poco::Net: std::string devid = pathPieces[matchPieces.size()]; auto device = repoService->getDevice(devid); if (!device.expired()) { - switch (dataMethod) { + switch (method) { case DeviceAPIMethod::GET: { std::string category; @@ -220,84 +284,14 @@ void DeviceRepoHandler::_handleGET(Poco::Net::HTTPServerRequest &req, Poco::Net: -void DeviceRepoHandler::_handlePOST(Poco::Net::HTTPServerRequest &req, Poco::Net::HTTPServerResponse &resp) { - throw webserver::webresource::WebResourceHandlerException("ToDo: Implement POST."); +void DeviceRepoInfoHandler::_handleGET(Poco::Net::HTTPServerRequest &req, Poco::Net::HTTPServerResponse &resp) { + Net::HTMLForm form(req); + __handle(req, resp, form); } - - -Variant DeviceRepoHandler::getDeviceInfo(devicerepository::Device* device, Net::HTTPServerRequest &req, const std::string& category, const std::vector& path) { - Variant retval; - - // We want all info categories - if (category.empty()) { - for (auto c : infoCategoryFuncs) { - retval[c.first] = c.second(matchUri, device, req, category, ssl); - } - - // We want a single info category - } else { - auto c = infoCategoryFuncs.find(category); - if (c != infoCategoryFuncs.end()) { - retval = c->second(matchUri, device, req, category, ssl); - if (path.size() > 0) { - std::stringstream ss; - for (auto p : path) { - ss << "/" << p; - } - std::string pathstr = ss.str(); - if (retval.HasPath(pathstr)) { - retval = retval.GetPath(pathstr); - } else { - throw webserver::webresource::WebResourceHandlerException((boost::format("Unknown path \"%1%\" for device info category \"%2%\".") % pathstr % 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); - } - } - - return retval; -} - - - -void DeviceRepoHandler::sendDeviceCommand(devicerepository::Device* device, Net::HTTPServerRequest &req, const std::string& cmd, const std::vector& path) { - Variant cmdMsg; - VariantRef mPart = cmdMsg.Ref(); - if (path.size() > 0) { - for (int i = 0; i < path.size(); i++) { - mPart[path[i]] = Variant(); - mPart.ReassignRef(mPart[path[i]]); - } - } - /* - * The libvariant json deserializer knows nothing about RFC 7159, therefore non-object or non-array values are rejected. - * As a workaround we use the yaml deserializer (yaml can be considered a super-set of json). - * Fun fact: the json serializer accepts non-object or non-array values. - */ - //mPart = DeserializeJSON(cmd); - mPart = DeserializeYAML(cmd); - device->sendCommand(cmdMsg); -} - -void DeviceRepoHandler::notificationReceived(interface::Observer::observable_type* o, const devicerepository::DeviceEventType& key, const devicerepository::DeviceEvent* e) noexcept { - switch (key) { - case devicerepository::DeviceEventType::DEVICE_ADDED: - break; - case devicerepository::DeviceEventType::DEVICE_REMOVED: - break; - case devicerepository::DeviceEventType::COMMAND_RECEIVED: - break; - case devicerepository::DeviceEventType::STATUS_UPDATE_RECEIVED: - break; - case devicerepository::DeviceEventType::STATE_CHANGED: - break; - default: - break; - } +void DeviceRepoInfoHandler::_handlePOST(Poco::Net::HTTPServerRequest &req, Poco::Net::HTTPServerResponse &resp) { + Net::HTMLForm form(req, req.stream()); + __handle(req, resp, form); } 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 fd3b0c70..a3885833 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 @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include @@ -27,7 +29,51 @@ namespace webresource { enum class DeviceAPIMethod { GET, COMMAND, - STATUSUPDATE + STATUSUPDATE, + REGISTEREVENT +}; + + +class DeviceEventQueue + : public virtual interface::Observer { +public: + const std::string clientID; + DeviceRepositoryService* const repoService; + DeviceEventType eventType; + Device* device; + std::string pointer; + std::queue eventQueue; + size_t openConnectionCount = 0; + + DeviceEventQueue( const std::string& clientID, + const DeviceEventType eventType, + DeviceRepositoryService* repoService, + Device* device, + std::string pointer ) + : clientID(clientID), eventType(eventType), repoService(repoService), device(device), pointer(pointer) {} + + virtual void notificationReceived( interface::Observer::observable_type* o, + const devicerepository::DeviceEventType& key, + const devicerepository::DeviceEvent* e) noexcept override { + if (eventType == DeviceEventType::ALL_EVENTS || eventType == key) { + switch (key) { + case devicerepository::DeviceEventType::COMMAND_RECEIVED: + break; + case devicerepository::DeviceEventType::STATUS_UPDATE_RECEIVED: + break; + case devicerepository::DeviceEventType::STATE_CHANGED: + break; + case devicerepository::DeviceEventType::DEVICE_ADDED: + break; + case devicerepository::DeviceEventType::DEVICE_REMOVED: + break; + default: + break; + } + } + } + }; @@ -43,8 +89,10 @@ public: bool ssl )> infoCategoryFunc_t; private: webserver::WebServerService* service = nullptr; - devicerepository::DeviceRepositoryService* repoService; + DeviceRepositoryService* repoService; std::map infoCategoryFuncs; + std::map> deviceEventQueues; + public: DeviceRepoHandlerFactory(devicerepository::DeviceRepositoryService* repoService); @@ -60,6 +108,12 @@ public: static DeviceAPIMethod getDeviceAPIMethod() noexcept; + std::shared_ptr getDeviceEventQueue( const std::string& clientID, + const DeviceEventType eventType, + DeviceRepositoryService* repoService, + Device* device, + std::string pointer ); + }; @@ -88,8 +142,7 @@ public: */ class DeviceRepoHandlerBase - : public interface::Observer, - public webserver::webresource::WebResourceHandlerImpl { + : public webserver::webresource::WebResourceHandlerImpl { protected: Poco::URI matchUri; @@ -116,56 +169,74 @@ public: bool ssl = false ) : matchUri(matchUri), repoService(repoService), infoCategoryFuncs(infoCategoryFuncs), ssl(ssl) {} +}; + + + +class DeviceRepoInfoHandler + : public DeviceRepoHandlerBase { + +protected: + DeviceAPIMethod method; + +public: + + DeviceRepoInfoHandler( Poco::URI matchUri, + DeviceAPIMethod method, + devicerepository::DeviceRepositoryService* repoService, + const std::map& infoCategoryFuncs, + bool ssl = false ) + : DeviceRepoHandlerBase(matchUri, repoService, infoCategoryFuncs, ssl), method(method) {} + virtual void _handleGET(Poco::Net::HTTPServerRequest &req, Poco::Net::HTTPServerResponse &resp) override; virtual void _handlePOST(Poco::Net::HTTPServerRequest &req, Poco::Net::HTTPServerResponse &resp) override; - virtual void notificationReceived( interface::Observer::observable_type* o, - const devicerepository::DeviceEventType& key, - const devicerepository::DeviceEvent* e) noexcept override; + virtual void __handle(Poco::Net::HTTPServerRequest &req, Poco::Net::HTTPServerResponse &resp, Poco::Net::HTMLForm& form); }; -class DeviceRepoHandler - : public interface::Observer, - public webserver::webresource::WebResourceHandlerImpl { +class DeviceRepoEventLongPollingHandler + : public DeviceRepoHandlerBase { -private: - Poco::URI matchUri; - devicerepository::DeviceRepositoryService* repoService; - const std::map& infoCategoryFuncs; - bool ssl; - - libvariant::Variant getDeviceInfo( devicerepository::Device* device, - Poco::Net::HTTPServerRequest &req, - const std::string& category = std::string(), - const std::vector& path = std::vector() ); - - void sendDeviceCommand( devicerepository::Device* device, - Poco::Net::HTTPServerRequest &req, - const std::string& cmd, - const std::vector& path = std::vector() ); +protected: public: - DeviceRepoHandler( Poco::URI matchUri, + DeviceRepoEventLongPollingHandler( Poco::URI matchUri, devicerepository::DeviceRepositoryService* repoService, const std::map& infoCategoryFuncs, bool ssl = false ) - : matchUri(matchUri), repoService(repoService), infoCategoryFuncs(infoCategoryFuncs), ssl(ssl) {} + : DeviceRepoHandlerBase(matchUri, repoService, infoCategoryFuncs, ssl) {} virtual void _handleGET(Poco::Net::HTTPServerRequest &req, Poco::Net::HTTPServerResponse &resp) override; virtual void _handlePOST(Poco::Net::HTTPServerRequest &req, Poco::Net::HTTPServerResponse &resp) override; - virtual void notificationReceived( interface::Observer::observable_type* o, - const devicerepository::DeviceEventType& key, - const devicerepository::DeviceEvent* e) noexcept override; +}; + + + +class DeviceRepoEventWebSocketHandler + : public DeviceRepoHandlerBase { + +protected: + + +public: + + DeviceRepoEventWebSocketHandler( Poco::URI matchUri, + devicerepository::DeviceRepositoryService* repoService, + const std::map& infoCategoryFuncs, + bool ssl = false ) + : DeviceRepoHandlerBase(matchUri, repoService, infoCategoryFuncs, ssl) {} + + virtual void _handleGET(Poco::Net::HTTPServerRequest &req, Poco::Net::HTTPServerResponse &resp) override; + + virtual void _handlePOST(Poco::Net::HTTPServerRequest &req, Poco::Net::HTTPServerResponse &resp) override; }; diff --git a/src/hos_cosgi_testwebapp/API-Notes.txt b/src/hos_cosgi_testwebapp/API-Notes.txt index 61891a3b..e57d64ef 100644 --- a/src/hos_cosgi_testwebapp/API-Notes.txt +++ b/src/hos_cosgi_testwebapp/API-Notes.txt @@ -2,12 +2,33 @@ HTTP - GET / HTTP - POST (application/x-www-form-urlencoded): ============================================================== x) [OUT] DeviceAPIMethod::GET [Args: format, pointer, query?] + -- http[s]:///devices[//] + x) [IN] DeviceAPIMethod::COMMAND [Args: format, pointer, msg] + -- http[s]:///devices/[/] + x) [IN] DeviceAPIMethod::STATUS_UPDATE [Args: format, pointer, msg] - x) [EVENT] DeviceAPIMethod::REGISTER_EVENT [Args: format, pointer, event] - - Long-Polling - - WebSocket + -- http[s]:///devices/[/] + x) [EVENT] DeviceAPIMethod::REGISTER_EVENT [Args: format, pointer, event] + -- http[s]:///devices/[/] + - Long-Polling + +HTTP - PUT: +============ + x) [IN] DeviceAPIMethod::COMMAND [Args: format, pointer, msg] + -- http[s]:///devices//command[/] + + x) [IN] DeviceAPIMethod::STATUS_UPDATE [Args: format, pointer, msg] + -- http[s]:///devices//statusupdate[/] + +HTTP - WebSocket: +================== + x) [EVENT] DeviceAPIMethod::REGISTER_EVENT [Args: format, pointer, event] + -- ws:///devices/[/] + + +============================================================== API Method Parameter: -- Query: method = get | command | statusupdate | event @@ -30,3 +51,8 @@ COMMAND/STATUS_UPDATE Parameters: EVENT Parameters: -- Query: event = command | statusupdate | statechange | added | removed | all + + +============================================================== + + 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 d4eef0ba..373158ad 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 @@ -261,6 +261,10 @@ protected: throw NotImplementedException(); } + virtual void _handlePUT(Poco::Net::HTTPServerRequest &req, Poco::Net::HTTPServerResponse &resp) { + throw NotImplementedException(); + } + virtual void handleRequest(Poco::Net::HTTPServerRequest &req, Poco::Net::HTTPServerResponse &resp) override { try { try { @@ -271,14 +275,16 @@ protected: _handleGET(req, resp); } else if (req.getMethod() == Poco::Net::HTTPRequest::HTTP_POST) { _handlePOST(req, resp); + } else if (req.getMethod() == Poco::Net::HTTPRequest::HTTP_PUT) { + _handlePUT(req, resp); } else { std::cout << "Unsupported HTTP Request Method" << std::endl; - handleErrorResponse(req, resp, (boost::format("HTTP method %1% not implemented") % req.getMethod()).str(), + handleErrorResponse(req, resp, (boost::format("HTTP method %1% not supported") % req.getMethod()).str(), Poco::Net::HTTPResponse::HTTPStatus::HTTP_NOT_IMPLEMENTED); } } catch (NotImplementedException& e) { std::cout << "Unsupported HTTP Request Method" << std::endl; - handleErrorResponse(req, resp, (boost::format("HTTP method %1% not implemented") % req.getMethod()).str(), + handleErrorResponse(req, resp, (boost::format("HTTP method %1% not supported") % req.getMethod()).str(), Poco::Net::HTTPResponse::HTTPStatus::HTTP_NOT_IMPLEMENTED); } }