Generate response for each of interface. (supported interfaces - oic.if.baseline, oic.if.a, oic.if.s, oic.if.b)
User can setting the default Interface.
If user not setting the default interface -> RE setting The default interface "oic.if.baseline"
Change-Id: If4faa93bb97850587bc44c7df5e6495796544c18
Signed-off-by: jaesick.shin <jaesick.shin@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/5195
Reviewed-by: JungHo Kim <jhyo.kim@samsung.com>
Tested-by: JungHo Kim <jhyo.kim@samsung.com>
#include <iostream>
#include "RCSDiscoveryManager.h"
+#include "RCSRepresentation.h"
#include "RCSRemoteResourceObject.h"
#include "RCSResourceAttributes.h"
#include "RCSAddress.h"
selectItem(items);
}
+std::string inputInterface()
+{
+ std::string interfaceName;
+
+ std::cout << "\tInput the Interface you want to set : ";
+ std::cin >> interfaceName;
+
+ return interfaceName;
+}
+
+RCSResourceAttributes inputKeyValue()
+{
+ std::string key;
+
+ std::cout << "\tEnter the Key you want to set : ";
+ std::cin >> key;
+
+ std::cout << "\tEnter the value(INT) you want to set :";
+ RCSResourceAttributes attrs;
+ attrs[key] = processUserInput();
+
+ return attrs;
+}
+
void printAttribute(const std::string& key, const RCSResourceAttributes::Value& value)
{
std::cout << "\tkey : " << key << std::endl
}
}
+void print(const std::string& name, const std::vector< std::string >& elements)
+{
+ if (elements.empty())
+ {
+ std::cout << "\t" << name << " is empty" << std::endl;
+ return;
+ }
+
+ std::cout << "\t" << name << " : " << std::endl;
+ for(const auto& item : elements)
+ {
+ std::cout << item << " ";
+ }
+ std::cout << std::endl;
+}
+
+void printUri(const std::string& uri)
+{
+ if(uri.empty())
+ {
+ std::cout << "\turi is empty" << std::endl;
+ }
+ else
+ {
+ std::cout << "\turi : " << uri << std::endl;
+ }
+}
+
+void printRepresentation(const RCSRepresentation& rep)
+{
+ printUri(rep.getUri());
+ print("interfaces", rep.getInterfaces());
+ print("resourceTypes", rep.getResourceTypes());
+ printAttributes(rep.getAttributes());
+
+ const auto& children = rep.getChildren();
+
+ if(children.empty())
+ {
+ std::cout << "\tchildren is empty" << std::endl;
+ }
+ else
+ {
+ int cnt = 0;
+ for(const auto& child : children)
+ {
+ std::cout << "========================================================" << std::endl;
+ std::cout << ++cnt << " chlid" << std::endl;
+ printRepresentation(child);
+ std::cout << "========================================================" << std::endl;
+ }
+ }
+}
+
void onResourceStateChanged(ResourceState resourceState)
{
std::cout << "onResourceStateChanged callback" << std::endl;
printAttributes(attributes);
}
+void onRemoteGetReceived(const HeaderOpts&, const RCSRepresentation& rep, int)
+{
+ std::cout << "onRemoteGetReceived callback" << std::endl;
+
+ printRepresentation(rep);
+}
+
+void onRemoteSetReceived(const HeaderOpts&, const RCSRepresentation& rep, int)
+{
+ std::cout << "onRemoteSetReceived callback" << std::endl;
+
+ printRepresentation(rep);
+}
+
void startMonitoring()
{
if (g_selectedResource->isMonitoring())
void setRemoteAttributes()
{
- std::string key;
+ g_selectedResource->setRemoteAttributes(inputKeyValue(), onRemoteAttributesReceived);
+}
- std::cout << "\tEnter the Key you want to set : ";
- std::cin >> key;
+void getWithInterface()
+{
+ RCSQueryParams queryParams;
+ queryParams.setResourceInterface(inputInterface());
- std::cout << "\tEnter the value(INT) you want to set :";
- RCSResourceAttributes attrs;
- attrs[key] = processUserInput();
+ g_selectedResource->get(queryParams, onRemoteGetReceived);
+}
+
+void setWithInterface()
+{
+ RCSQueryParams queryParams;
+ queryParams.setResourceInterface(inputInterface());
- g_selectedResource->setRemoteAttributes(attrs, onRemoteAttributesReceived);
+ g_selectedResource->set(queryParams, inputKeyValue(), onRemoteSetReceived);
}
void startCaching(RCSRemoteResourceObject::CacheUpdatedCallback cb)
DECLARE_MENU(stopMonitoring),
DECLARE_MENU(getRemoteAttributes),
DECLARE_MENU(setRemoteAttributes),
+ DECLARE_MENU(getWithInterface),
+ DECLARE_MENU(setWithInterface),
DECLARE_MENU(startCachingWithoutCallback),
DECLARE_MENU(startCachingWithCallback),
DECLARE_MENU(getResourceCacheState),
constexpr int INCREASE = 1;
constexpr int DECREASE = 2;
+const std::string BASELINE_INTERFACE = "oic.if.baseline";
+const std::string ACTUATOR_INTERFACE = "oic.if.a";
+const std::string SENSOR_INTERFACE = "oic.if.s";
+const std::string CUSTOM_INTERFACE = "test.custom";
+
typedef void (*DisplayControlMenuFunc)();
typedef std::function<void()> Run;
void initServer(const std::string& resourceUri, const std::string& resourceType,
const std::string& attrKey)
{
- g_resource = RCSResourceObject::Builder(resourceUri, resourceType, "oic.if.").
- setDiscoverable(true).setObservable(true).build();
+ g_resource = RCSResourceObject::Builder(resourceUri, resourceType, ACTUATOR_INTERFACE)
+ .addInterface(CUSTOM_INTERFACE)
+ .addInterface(SENSOR_INTERFACE)
+ .setDefaultInterface(SENSOR_INTERFACE)
+ .setDiscoverable(true)
+ .setObservable(true)
+ .build();
g_resource->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::UPDATED);
g_resource->setSetRequestHandlerPolicy(RCSResourceObject::SetRequestHandlerPolicy::NEVER);
#include <string>
#include <mutex>
#include <thread>
+#include <map>
#include "RCSResourceAttributes.h"
#include "RCSResponse.h"
class RCSRequest;
class RCSRepresentation;
+ class InterfaceHandler;
/**
* @brief Thrown when lock has not been acquired.
Builder& addType(std::string&& type);
/**
+ * Sets the default interface
+ *
+ * @param interface default interface name
+ *
+ */
+ Builder& setDefaultInterface(std::string interface);
+
+ /**
* Sets whether the resource is discoverable.
*
* @param discoverable whether to be discoverable.
std::string m_uri;
std::vector< std::string > m_types;
std::vector< std::string > m_interfaces;
+ std::string m_defaultInterface;
uint8_t m_properties;
RCSResourceAttributes m_resourceAttributes;
};
std::vector< RCSResourceObject::Ptr > getBoundResources() const;
+ std::string getUri() const;
+ std::string getDefaultInterface() const;
+
std::vector< std::string > getInterfaces() const;
std::vector< std::string > getTypes() const;
private:
RCSResourceObject(const std::string&, uint8_t, RCSResourceAttributes&&);
+ void init(OCResourceHandle, const std::vector< std::string >&,
+ const std::vector< std::string >&, const std::string&);
+
static OCEntityHandlerResult entityHandler(const std::weak_ptr< RCSResourceObject >&,
const std::shared_ptr< OC::OCResourceRequest >&);
OCEntityHandlerResult handleRequest(const std::shared_ptr< OC::OCResourceRequest >&);
- OCEntityHandlerResult handleRequestGet(const std::shared_ptr< OC::OCResourceRequest >&);
- OCEntityHandlerResult handleRequestSet(const std::shared_ptr< OC::OCResourceRequest >&);
+ OCEntityHandlerResult handleRequestGet(const RCSRequest&);
+ OCEntityHandlerResult handleRequestSet(const RCSRequest&);
OCEntityHandlerResult handleObserve(const std::shared_ptr< OC::OCResourceRequest >&);
+ template <typename RESPONSE, typename RESPONSE_BUILDER>
+ OCEntityHandlerResult sendResponse(const RCSRequest&,
+ const RESPONSE&, const RESPONSE_BUILDER&);
+
void expectOwnLock() const;
std::thread::id getLockOwner() const noexcept;
template< typename K, typename V >
void setAttributeInternal(K&&, V&&);
- bool applyAcceptanceMethod(const RCSSetResponse&, const RCSResourceAttributes&);
+ RCSResourceAttributes applyAcceptanceMethod(const RCSSetResponse&,
+ const RCSResourceAttributes&);
+
+ InterfaceHandler findInterfaceHandler(const std::string&) const;
private:
const uint8_t m_properties;
const std::string m_uri;
std::vector< std::string > m_interfaces;
std::vector< std::string > m_types;
+ std::string m_defaultInterface;
OCResourceHandle m_resourceHandle;
std::vector< RCSResourceObject::Ptr > m_boundResources;
+ std::map< std::string, InterfaceHandler > m_interfaceHandlers;
+
};
/**
--- /dev/null
+//******************************************************************\r
+//\r
+// Copyright 2015 Samsung Electronics All Rights Reserved.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//\r
+// http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+\r
+#ifndef RE_INTERFACEHANDLER_H_\r
+#define RE_INTERFACEHANDLER_H_\r
+\r
+#include <string>\r
+#include <functional>\r
+\r
+namespace OIC\r
+{\r
+ namespace Service\r
+ {\r
+ class RCSRequest;\r
+ class RCSResourceObject;\r
+ class RCSRepresentation;\r
+ class RCSResourceAttributes;\r
+\r
+ const std::string BASELINE_INTERFACE = "oic.if.baseline";\r
+ const std::string ACTUATOR_INTERFACE = "oic.if.a";\r
+ const std::string SENSOR_INTERFACE = "oic.if.s";\r
+ const std::string BATCH_INTERFACE = "oic.if.b";\r
+\r
+ class InterfaceHandler\r
+ {\r
+ public:\r
+ typedef std::function< RCSRepresentation(RCSRequest, RCSResourceObject&) >\r
+ GetResponseBuilder;\r
+\r
+ typedef std::function< RCSRepresentation(RCSRequest, RCSResourceObject&) >\r
+ SetResponseBuilder;\r
+\r
+ public:\r
+ InterfaceHandler(GetResponseBuilder, SetResponseBuilder);\r
+\r
+ bool isGetSupported() const;\r
+ bool isSetSupported() const;\r
+\r
+ GetResponseBuilder getGetResponseBuilder() const;\r
+ SetResponseBuilder getSetResponseBuilder() const;\r
+\r
+ private:\r
+ GetResponseBuilder m_getBuilder;\r
+ SetResponseBuilder m_setBuilder;\r
+ };\r
+\r
+ InterfaceHandler getDefaultInterfaceHandler(const std::string&, const std::string&);\r
+ }\r
+}\r
+\r
+#endif /* RE_INTERFACEHANDLER_H_ */\r
#ifndef SERVERBUILDER_REQUESTHANDLER_H
#define SERVERBUILDER_REQUESTHANDLER_H
-#include <RCSResponse.h>
-#include <RCSResourceAttributes.h>
+#include "RCSResponse.h"
+#include "RCSResourceAttributes.h"
namespace OC
{
- class OCResourceResponse;
class OCRepresentation;
}
class RequestHandler
{
private:
- typedef std::function< std::shared_ptr< OC::OCResourceResponse >(RCSResourceObject&) >
- BuildResponseHolder;
+ typedef std::function< OC::OCRepresentation() > RepresentationBuilder;
public:
- typedef std::shared_ptr< RequestHandler > Pre;
-
- static constexpr int DEFAULT_ERROR_CODE = 200;
RequestHandler();
virtual ~RequestHandler() { };
- std::shared_ptr< OC::OCResourceResponse > buildResponse(RCSResourceObject&);
+ int getErrorCode() const;
+
+ bool hasCustomRepresentation() const;
+
+ OC::OCRepresentation getRepresentation() const;
+
+ public:
+ static constexpr int DEFAULT_ERROR_CODE = 200;
private:
- const BuildResponseHolder m_holder;
+ const int m_errorCode;
+ const RepresentationBuilder m_repBuilder;
};
class SetRequestHandler: public RequestHandler
--- /dev/null
+#include "InterfaceHandler.h"\r
+\r
+#include "OCApi.h"\r
+#include "OCResourceRequest.h"\r
+\r
+#include "RCSRepresentation.h"\r
+#include "RCSRequest.h"\r
+#include "RCSResourceObject.h"\r
+#include "RCSResourceAttributes.h"\r
+#include "ResourceAttributesConverter.h"\r
+\r
+#include <unordered_map>\r
+\r
+namespace\r
+{\r
+ using namespace OIC::Service;\r
+\r
+ RCSRepresentation buildGetBaselineResponse(const RCSRequest&, RCSResourceObject& resource)\r
+ {\r
+ RCSResourceObject::LockGuard lock(resource);\r
+\r
+ return RCSRepresentation{ resource.getUri(), resource.getInterfaces(), resource.getTypes(),\r
+ resource.getAttributes()};\r
+ }\r
+\r
+ RCSRepresentation buildSetBaselineResponse(const RCSRequest& rcsRequest, RCSResourceObject& resource)\r
+ {\r
+ return buildGetBaselineResponse(rcsRequest, resource);\r
+ }\r
+\r
+ RCSRepresentation buildGetRequestResponse(const RCSRequest&, RCSResourceObject& resource)\r
+ {\r
+ RCSResourceObject::LockGuard lock(resource);\r
+\r
+ return RCSRepresentation{resource.getAttributes()};\r
+ }\r
+\r
+ RCSRepresentation buildSetRequestResponse(const RCSRequest& rcsRequest, RCSResourceObject& resource)\r
+ {\r
+ auto requestAttr = ResourceAttributesConverter::fromOCRepresentation(\r
+ (rcsRequest.getOCRequest())->getResourceRepresentation());\r
+\r
+ RCSResourceObject::LockGuard lock(resource);\r
+\r
+ const RCSResourceAttributes& updatedAttr = resource.getAttributes();\r
+\r
+ for (auto& kvPair : requestAttr)\r
+ {\r
+ if(updatedAttr.contains(kvPair.key()))\r
+ {\r
+ kvPair.value() = updatedAttr.at(kvPair.key());\r
+ }\r
+ else\r
+ {\r
+ //FIXME erase item with iterator.\r
+ requestAttr.erase(kvPair.key());\r
+ }\r
+ }\r
+\r
+ return RCSRepresentation{ requestAttr };\r
+ }\r
+\r
+ RCSRepresentation buildGetBatchResponse(RCSRequest, RCSResourceObject& resource)\r
+ {\r
+ RCSRepresentation rcsRep;\r
+\r
+ for (const auto& bound : resource.getBoundResources())\r
+ {\r
+ rcsRep.addChild(bound->toRepresentation());\r
+ }\r
+\r
+ return rcsRep;\r
+ }\r
+\r
+ const std::unordered_map< std::string, InterfaceHandler > g_defaultHandlers {\r
+\r
+ { BASELINE_INTERFACE,\r
+ InterfaceHandler(buildGetBaselineResponse, buildSetBaselineResponse) },\r
+\r
+ { ACTUATOR_INTERFACE,\r
+ InterfaceHandler(buildGetRequestResponse, buildSetRequestResponse) },\r
+\r
+ { SENSOR_INTERFACE,\r
+ InterfaceHandler(buildGetRequestResponse, nullptr) },\r
+\r
+ { BATCH_INTERFACE,\r
+ InterfaceHandler(buildGetBatchResponse, buildSetBaselineResponse) }\r
+ };\r
+}\r
+\r
+namespace OIC\r
+{\r
+ namespace Service\r
+ {\r
+\r
+ InterfaceHandler::InterfaceHandler(GetResponseBuilder getBuilder,\r
+ SetResponseBuilder setBuilder) :\r
+ m_getBuilder{ std::move(getBuilder) },\r
+ m_setBuilder{ std::move(setBuilder) }\r
+ {\r
+ }\r
+\r
+ bool InterfaceHandler::isGetSupported() const\r
+ {\r
+ return m_getBuilder != nullptr;\r
+ }\r
+\r
+ bool InterfaceHandler::isSetSupported() const\r
+ {\r
+ return m_setBuilder != nullptr;\r
+ }\r
+\r
+ InterfaceHandler::GetResponseBuilder InterfaceHandler::getGetResponseBuilder() const\r
+ {\r
+ return m_getBuilder;\r
+ }\r
+\r
+ InterfaceHandler::SetResponseBuilder InterfaceHandler::getSetResponseBuilder() const\r
+ {\r
+ return m_setBuilder;\r
+ }\r
+\r
+ InterfaceHandler getDefaultInterfaceHandler(const std::string& interfaceName,\r
+ const std::string& defaultInterfaceName)\r
+ {\r
+ auto it = g_defaultHandlers.find(interfaceName);\r
+ if (it != g_defaultHandlers.end()) return it->second;\r
+\r
+ it = g_defaultHandlers.find(defaultInterfaceName);\r
+ if (it != g_defaultHandlers.end()) return it->second;\r
+\r
+ return g_defaultHandlers.find(OIC::Service::BASELINE_INTERFACE)->second;\r
+ }\r
+ }\r
+}\r
#include "RCSResourceObject.h"
-#include <string>
#include <functional>
#include <vector>
#include "ResourceAttributesUtils.h"
#include "RCSRequest.h"
#include "RCSRepresentation.h"
+#include "InterfaceHandler.h"
#include "logger.h"
#include "OCPlatform.h"
return base & ~target;
}
- inline bool requestContainsInterface(const std::shared_ptr< OC::OCResourceRequest >& request,
- const std::string& interface)
- {
- auto it = request->getQueryParameters().find(OC::Key::INTERFACESKEY);
-
- if (it == request->getQueryParameters().end()) return false;
-
- return it->second == interface;
- }
-
OCEntityHandlerResult sendResponse(const std::shared_ptr< OC::OCResourceRequest >& ocRequest,
const std::shared_ptr< OC::OCResourceResponse >& ocResponse)
{
return OC_EH_ERROR;
}
-
- template <typename RESPONSE>
- OCEntityHandlerResult sendResponse(RCSResourceObject& resource,
- const std::shared_ptr< OC::OCResourceRequest >& ocRequest, RESPONSE&& response)
- {
- return sendResponse(ocRequest, response.getHandler()->buildResponse(resource));
- }
-
RCSResourceAttributes getAttributesFromOCRequest(
const std::shared_ptr< OC::OCResourceRequest >& request)
{
(bool, RCSResourceObject::AutoNotifyPolicy) const;
std::function<void()> createAutoNotifyInvoker(AutoNotifyFunc autoNotifyFunc,
- const RCSResourceObject& resourceObject, const RCSResourceAttributes& resourceAttributes,
+ const RCSResourceObject& resourceObject,
+ const RCSResourceAttributes& resourceAttributes,
RCSResourceObject::AutoNotifyPolicy autoNotifyPolicy)
{
if(autoNotifyPolicy == RCSResourceObject::AutoNotifyPolicy::UPDATED)
return {};
}
- OCEntityHandlerResult handleBatchInterfaceGetRequest(
- const std::shared_ptr< OC::OCResourceRequest >& request,
- const RCSResourceObject* resourceObject)
- {
- RCSRepresentation rcsRep;
-
- for (const auto& bound : resourceObject->getBoundResources())
- {
- rcsRep.addChild(bound->toRepresentation());
- }
-
- auto response = std::make_shared< OC::OCResourceResponse >();
-
- response->setResponseResult(OC_EH_OK);
- response->setErrorCode(200);
- response->setResourceRepresentation(
- RCSRepresentation::toOCRepresentation(std::move(rcsRep)));
-
- return sendResponse(request, response);
- }
-
} // unnamed namespace
namespace OIC
m_uri{ uri },
m_types{ type },
m_interfaces{ interface },
+ m_defaultInterface { BASELINE_INTERFACE },
m_properties{ OC_DISCOVERABLE | OC_OBSERVABLE },
m_resourceAttributes{ }
{
return *this;
}
+ RCSResourceObject::Builder& RCSResourceObject::Builder::setDefaultInterface(
+ std::string interface)
+ {
+ if (std::find(m_interfaces.begin(), m_interfaces.end(), interface) ==
+ m_interfaces.end())
+ {
+ throw RCSBadRequestException{"The interface should be added, first."};
+ }
+
+ m_defaultInterface = std::move(interface);
+
+ return *this;
+ }
+
RCSResourceObject::Builder& RCSResourceObject::Builder::setDiscoverable(
bool discoverable)
{
invokeOCFunc(OC::OCPlatform::bindTypeToResource, handle, typeName);
});
- server->m_resourceHandle = handle;
- server->m_interfaces = m_interfaces;
- server->m_types = m_types;
+ server->init(handle, m_interfaces, m_types, m_defaultInterface);
return server;
}
m_uri{ uri },
m_interfaces{ },
m_types{ },
+ m_defaultInterface{ },
m_resourceHandle{ },
m_resourceAttributes{ std::move(attrs) },
m_getRequestHandler{ },
m_lockOwner.reset(new AtomicThreadId);
}
+ void RCSResourceObject::init(OCResourceHandle handle,
+ const std::vector< std::string >& interfaces,
+ const std::vector< std::string >& types,
+ const std::string& defaultInterface)
+ {
+ m_resourceHandle = handle;
+ m_interfaces = interfaces;
+ m_types = types;
+ m_defaultInterface = defaultInterface;
+
+ for (const auto& itf : interfaces)
+ {
+ m_interfaceHandlers.insert({ itf, getDefaultInterfaceHandler(itf,
+ m_defaultInterface) });
+ }
+ }
+
RCSResourceObject::~RCSResourceObject()
{
if (m_resourceHandle)
return m_boundResources;
}
+ std::string RCSResourceObject::getUri() const
+ {
+ return m_uri;
+ }
+
+ std::string RCSResourceObject::getDefaultInterface() const
+ {
+ return m_defaultInterface;
+ }
+
std::vector< std::string > RCSResourceObject::getInterfaces() const
{
return m_interfaces;
{
WeakGuard lock{*this};
return RCSRepresentation{ m_uri, m_interfaces, m_types, m_resourceAttributes };
- }
+ }
void RCSResourceObject::autoNotify(bool isAttributesChanged) const
{
{
assert(request != nullptr);
+ RCSRequest rcsRequest{ shared_from_this(), request };
+
+ if (rcsRequest.getInterface() != "" && m_interfaceHandlers.find(
+ rcsRequest.getInterface()) == m_interfaceHandlers.end())
+ {
+ return OC_EH_ERROR;
+ }
+
if (request->getRequestType() == "GET")
{
- return handleRequestGet(request);
+ return handleRequestGet(rcsRequest);
}
if (request->getRequestType() == "POST")
{
- return handleRequestSet(request);
+ return handleRequestSet(rcsRequest);
}
return OC_EH_ERROR;
}
OCEntityHandlerResult RCSResourceObject::handleRequestGet(
- const std::shared_ptr< OC::OCResourceRequest >& request)
+ const RCSRequest& request)
{
- assert(request != nullptr);
-
- if (requestContainsInterface(request, OC::BATCH_INTERFACE))
+ if (!findInterfaceHandler(request.getInterface()).isGetSupported())
{
- return handleBatchInterfaceGetRequest(request, this);
+ return OC_EH_ERROR;
}
- auto attrs = getAttributesFromOCRequest(request);
+ auto attrs = getAttributesFromOCRequest(request.getOCRequest());
- auto response = invokeHandler(shared_from_this(), attrs, request, m_getRequestHandler);
+ auto response = invokeHandler(shared_from_this(), attrs, request.getOCRequest(),
+ m_getRequestHandler);
if (response.isSeparate()) return OC_EH_SLOW;
- return sendResponse(*this, request, response);
+ return sendResponse(request, response,
+ findInterfaceHandler(request.getInterface()).getGetResponseBuilder());
}
- bool RCSResourceObject::applyAcceptanceMethod(const RCSSetResponse& response,
- const RCSResourceAttributes& requstAttrs)
+ RCSResourceAttributes RCSResourceObject::applyAcceptanceMethod(
+ const RCSSetResponse& response, const RCSResourceAttributes& requestAttrs)
{
auto requestHandler = response.getHandler();
assert(requestHandler != nullptr);
+ RCSResourceAttributes result;
+
auto replaced = requestHandler->applyAcceptanceMethod(response.getAcceptanceMethod(),
- *this, requstAttrs);
+ *this, requestAttrs);
OIC_LOG_V(WARNING, LOG_TAG, "replaced num %zu", replaced.size());
for (const auto& attrKeyValPair : replaced)
if (foundListener)
{
- (*foundListener)(attrKeyValPair.second, requstAttrs.at(attrKeyValPair.first));
+ (*foundListener)(attrKeyValPair.second, requestAttrs.at(attrKeyValPair.first));
}
+
+ result[attrKeyValPair.first] = attrKeyValPair.second;
}
- return !replaced.empty();
+ return result;
}
OCEntityHandlerResult RCSResourceObject::handleRequestSet(
- const std::shared_ptr< OC::OCResourceRequest >& request)
+ const RCSRequest& request)
{
- assert(request != nullptr);
+ if (!findInterfaceHandler(request.getInterface()).isSetSupported())
+ {
+ return OC_EH_ERROR;
+ }
+
+ auto attrs = getAttributesFromOCRequest(request.getOCRequest());
- auto attrs = getAttributesFromOCRequest(request);
- auto response = invokeHandler(shared_from_this(), attrs, request, m_setRequestHandler);
+ auto response = invokeHandler(shared_from_this(), attrs, request.getOCRequest(),
+ m_setRequestHandler);
if (response.isSeparate()) return OC_EH_SLOW;
- auto attrsChanged = applyAcceptanceMethod(response, attrs);
+ auto replaced = applyAcceptanceMethod(response, attrs);
- try
- {
- autoNotify(attrsChanged, m_autoNotifyPolicy);
- return sendResponse(*this, request, response);
- } catch (const RCSPlatformException& e) {
- OIC_LOG_V(ERROR, LOG_TAG, "Error : %s ", e.what());
- return OC_EH_ERROR;
- }
+ autoNotify(!replaced.empty(), m_autoNotifyPolicy);
+
+ return sendResponse(request, response,
+ findInterfaceHandler(request.getInterface()).getSetResponseBuilder());
}
OCEntityHandlerResult RCSResourceObject::handleObserve(
return OC_EH_OK;
}
+ InterfaceHandler RCSResourceObject::findInterfaceHandler(
+ const std::string& interfaceName) const
+ {
+ auto it = m_interfaceHandlers.find(interfaceName);
+
+ if (it != m_interfaceHandlers.end()) return it->second;
+
+ assert(m_interfaceHandlers.find(m_defaultInterface) != m_interfaceHandlers.end());
+
+ return m_interfaceHandlers.find(m_defaultInterface)->second;
+ }
+
+ template <typename RESPONSE, typename RESPONSE_BUILDER>
+ OCEntityHandlerResult RCSResourceObject::sendResponse(
+ const RCSRequest& request, const RESPONSE& response,
+ const RESPONSE_BUILDER& resBuilder)
+ {
+ auto reqHandler = response.getHandler();
+ auto ocResponse = std::make_shared< OC::OCResourceResponse >();
+
+ ocResponse->setResponseResult(OC_EH_OK);
+ ocResponse->setErrorCode(reqHandler->getErrorCode());
+
+ if (reqHandler->hasCustomRepresentation())
+ {
+ ocResponse->setResourceRepresentation(reqHandler->getRepresentation());
+ }
+ else
+ {
+ ocResponse->setResourceRepresentation(
+ RCSRepresentation::toOCRepresentation(
+ resBuilder(request, *this)));
+ }
+
+ return ::sendResponse(request.getOCRequest(), ocResponse);
+ }
+
+
RCSResourceObject::LockGuard::LockGuard(const RCSResourceObject::Ptr ptr) :
m_resourceObject(*ptr),
m_autoNotifyPolicy{ ptr->getAutoNotifyPolicy() },
{
using namespace OIC::Service;
- typedef std::function< OC::OCRepresentation(RCSResourceObject&) > OCRepresentationGetter;
-
- OC::OCRepresentation getOCRepresentationFromResource(RCSResourceObject& resource)
- {
- RCSResourceObject::LockGuard lock{ resource, RCSResourceObject::AutoNotifyPolicy::NEVER };
- return ResourceAttributesConverter::toOCRepresentation(resource.getAttributes());
- }
-
- OC::OCRepresentation getOCRepresentation(const RCSResourceAttributes& attrs)
- {
- return ResourceAttributesConverter::toOCRepresentation(attrs);
- }
-
- template< typename T >
- OCRepresentationGetter wrapGetOCRepresentation(T&& attrs)
- {
- return std::bind(getOCRepresentation, std::forward<T>(attrs));
- }
-
- std::shared_ptr< OC::OCResourceResponse > doBuildResponse(RCSResourceObject& resource,
- int errorCode, OCRepresentationGetter ocRepGetter)
- {
- auto response = std::make_shared< OC::OCResourceResponse >();
-
- response->setResponseResult(OC_EH_OK);
- response->setErrorCode(errorCode);
- response->setResourceRepresentation(ocRepGetter(resource));
-
- return response;
- }
-
AttrKeyValuePairs applyAcceptMethod(RCSResourceObject& resource,
const RCSResourceAttributes& requestAttrs)
{
constexpr int RequestHandler::DEFAULT_ERROR_CODE;
RequestHandler::RequestHandler() :
- m_holder{ std::bind(doBuildResponse, std::placeholders::_1, DEFAULT_ERROR_CODE,
- getOCRepresentationFromResource) }
+ m_errorCode{ DEFAULT_ERROR_CODE },
+ m_repBuilder{ }
{
}
RequestHandler::RequestHandler(int errorCode) :
- m_holder{ std::bind(doBuildResponse, std::placeholders::_1, errorCode,
- getOCRepresentationFromResource) }
+ m_errorCode{ errorCode },
+ m_repBuilder{ }
+
{
}
RequestHandler::RequestHandler(const RCSResourceAttributes& attrs, int errorCode) :
- m_holder{ std::bind(doBuildResponse, std::placeholders::_1, errorCode,
- wrapGetOCRepresentation(attrs)) }
+ m_errorCode{ errorCode },
+ m_repBuilder{ std::bind(ResourceAttributesConverter::toOCRepresentation, attrs) }
{
}
RequestHandler::RequestHandler(RCSResourceAttributes&& attrs, int errorCode) :
- m_holder{ std::bind(doBuildResponse, std::placeholders::_1, errorCode,
- wrapGetOCRepresentation(std::move(attrs))) }
+ m_errorCode{ errorCode },
+ m_repBuilder{ std::bind(ResourceAttributesConverter::toOCRepresentation,
+ std::move(attrs)) }
{
}
- std::shared_ptr< OC::OCResourceResponse > RequestHandler::buildResponse(
- RCSResourceObject& resource)
+ int RequestHandler::getErrorCode() const
{
- return m_holder(resource);
+ return m_errorCode;
}
+ bool RequestHandler::hasCustomRepresentation() const
+ {
+ return m_repBuilder != nullptr;
+ }
+
+ OC::OCRepresentation RequestHandler::getRepresentation() const
+ {
+ assert(m_repBuilder);
+ return m_repBuilder();
+ }
SetRequestHandler::SetRequestHandler() :
RequestHandler{ }
using namespace OIC::Service;
using namespace OC;
-typedef OCStackResult (*registerResourceSig)(OCResourceHandle&,
- string&,
- const string&,
- const string&,
- EntityHandler,
- uint8_t );
-
-static constexpr char KEY[] = "key";
-
-
-void EXPECT_RESPONSE(shared_ptr< OCResourceResponse > ocResponse, int errorCode,
- const RCSResourceAttributes& attrs)
-{
- EXPECT_EQ(ocResponse->getErrorCode(), errorCode);
- EXPECT_EQ(ResourceAttributesConverter::fromOCRepresentation(
- ocResponse->getResourceRepresentation()), attrs);
-}
-
-
-class RCSResponseTest: public TestWithMock
-{
-public:
- template< typename T >
- shared_ptr< OCResourceResponse > buildResponse(const T& response)
- {
- RCSResourceObject::Ptr server =
- RCSResourceObject::Builder("a/test", "", "").build();
-
- return response.getHandler()->buildResponse(*server);
- }
-
-protected:
- void SetUp()
- {
- TestWithMock::SetUp();
-
- mocks.OnCallFuncOverload(static_cast< registerResourceSig >(OCPlatform::registerResource))
- .Return(OC_STACK_OK);
-
- mocks.OnCallFunc(OCPlatform::unregisterResource).Return(OC_STACK_OK);
- }
-};
-
-TEST_F(RCSResponseTest, GetDefaultActionHasEmptyAttrs)
-{
- EXPECT_RESPONSE(buildResponse(RCSGetResponse::defaultAction()),
- RequestHandler::DEFAULT_ERROR_CODE, RCSResourceAttributes());
-}
-
-TEST_F(RCSResponseTest, GetResponseHasResultsPassedCodes)
-{
- constexpr int errorCode{ -10 };
-
- EXPECT_RESPONSE(buildResponse(RCSGetResponse::create(errorCode)),
- errorCode, RCSResourceAttributes());
-}
-
-TEST_F(RCSResponseTest, GetResponseHasAttrsAndResultsPassedCodes)
-{
- constexpr int errorCode{ -10 };
-
- RCSResourceAttributes attrs;
- attrs[KEY] = 100;
-
- EXPECT_RESPONSE(buildResponse(RCSGetResponse::create(attrs, errorCode)), errorCode, attrs);
-}
-
-TEST_F(RCSResponseTest, GetResponseCanMoveAttrs)
-{
- constexpr int errorCode{ -10 };
-
- RCSResourceAttributes attrs;
- attrs[KEY] = 100;
-
- RCSResourceAttributes attrsClone;
- attrsClone[KEY] = 100;
-
- EXPECT_RESPONSE(
- buildResponse(RCSGetResponse::create(std::move(attrs), errorCode)),
- errorCode, attrsClone);
-
- EXPECT_TRUE(attrs.empty());
-}
-
-TEST_F(RCSResponseTest, SetDefaultActionHasEmptyAttrs)
-{
- EXPECT_RESPONSE(buildResponse(RCSSetResponse::defaultAction()),
- RequestHandler::DEFAULT_ERROR_CODE, RCSResourceAttributes());
-}
-
-TEST_F(RCSResponseTest, SetResponseHasResultsPassedCodes)
-{
- constexpr int errorCode{ -10 };
-
- EXPECT_RESPONSE(buildResponse(RCSSetResponse::create(errorCode)),
- errorCode, RCSResourceAttributes());
-}
-
-TEST_F(RCSResponseTest, SetResponseHasAttrsAndResultsPassedCodes)
-{
- constexpr int errorCode{ -10 };
-
- RCSResourceAttributes attrs;
- attrs[KEY] = 100;
-
- EXPECT_RESPONSE(buildResponse(RCSSetResponse::create(attrs, errorCode)),
- errorCode, attrs);
-}
-
-TEST_F(RCSResponseTest, SetResponseCanMoveAttrs)
-{
- constexpr int errorCode{ -10 };
-
- RCSResourceAttributes attrs;
- attrs[KEY] = 100;
-
- RCSResourceAttributes attrsClone;
- attrsClone[KEY] = 100;
-
- EXPECT_RESPONSE(buildResponse(RCSSetResponse::create(std::move(attrs), errorCode)),
- errorCode, attrsClone);
-
- EXPECT_TRUE(attrs.empty());
-}
-
-
-TEST_F(RCSResponseTest, DefaultSetResponseHasDefaultMethod)
+TEST(RCSResponseTest, DefaultSetResponseHasDefaultMethod)
{
EXPECT_EQ(RCSSetResponse::AcceptanceMethod::DEFAULT,
RCSSetResponse::defaultAction().getAcceptanceMethod());
}
-TEST_F(RCSResponseTest, AcceptSetResponseHasAcceptMethod)
+TEST(RCSResponseTest, AcceptSetResponseHasAcceptMethod)
{
EXPECT_EQ(RCSSetResponse::AcceptanceMethod::ACCEPT,
RCSSetResponse::accept().getAcceptanceMethod());
}
-TEST_F(RCSResponseTest, IgnoreSetResponseHasIgnoreMethod)
+TEST(RCSResponseTest, IgnoreSetResponseHasIgnoreMethod)
{
EXPECT_EQ(RCSSetResponse::AcceptanceMethod::IGNORE,
RCSSetResponse::ignore().getAcceptanceMethod());
}
-TEST_F(RCSResponseTest, SetResponseHasMethodSetBySetter)
+TEST(RCSResponseTest, SetResponseHasMethodSetBySetter)
{
RCSSetResponse::AcceptanceMethod method = RCSSetResponse::AcceptanceMethod::ACCEPT;
RCSSetResponse response =
EXPECT_EQ(method, response.getAcceptanceMethod());
}
-TEST_F(RCSResponseTest, SeparateResponseHasNoHandler)
+TEST(RCSResponseTest, SeparateResponseHasNoHandler)
{
RCSGetResponse response = RCSGetResponse::separate();
EXPECT_EQ(nullptr, response.getHandler());
}
-TEST_F(RCSResponseTest, ThrowIfRequestIsInvalidWhenConstructingSeparateResponse)
+TEST(RCSResponseTest, ThrowIfRequestIsInvalidWhenConstructingSeparateResponse)
{
RCSRequest aRequest;
typedef OCStackResult (*RegisterResource)(OCResourceHandle&, std::string&,
const std::string&, const std::string&, OC::EntityHandler, uint8_t);
+
class RequestHandlerTest: public TestWithMock
{
public:
}
};
-TEST_F(RequestHandlerTest, ResponseHasSameValuesPassedToHandlerConstructor)
-{
- RequestHandler handler{ -1000 };
-
- auto response = handler.buildResponse(*server);
-
- ASSERT_EQ(-1000, response->getErrorCode());
-}
-
-TEST_F(RequestHandlerTest, ResponseHasSameAttrsWithServerAttrs)
-{
- RequestHandler handler{};
-
- auto response = handler.buildResponse(*server);
-
- ASSERT_EQ(ORIGIN_VALUE, response->getResourceRepresentation()[EXISTING].getValue<int>());
-}
-
-TEST_F(RequestHandlerTest, ResponseHasAttrsSetByCustomAttrRequestHandler)
-{
- constexpr char key[] { "key" };
- constexpr int newValue{ 100 };
-
- RCSResourceAttributes attrs;
- attrs[key] = newValue;
- RequestHandler handler{ attrs };
-
- auto response = handler.buildResponse(*server);
-
- ASSERT_EQ(ORIGIN_VALUE, response->getResourceRepresentation()[key].getValue<int>());
-}
-
-
-
class SetRequestHandlerAcceptanceTest: public RequestHandlerTest
{
public: