replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / service / resource-encapsulation / src / resourceClient / RCSRemoteResourceObject.cpp
index f8d4067..bc95aa9 100644 (file)
 
 #include "RCSRemoteResourceObject.h"
 
+#include "OCPlatform.h"
+
 #include "ResourceBroker.h"
 #include "ResourceCacheManager.h"
 
 #include "ScopeLogger.h"
 
-#define TAG "RCSRemoteResourceObject"
+#define TAG PCF("RCSRemoteResourceObject")
 
 namespace
 {
@@ -90,29 +92,57 @@ namespace
     }
 
     OCStackResult cachingCallback(std::shared_ptr< PrimitiveResource >,
-            const RCSResourceAttributes& data,
-            RCSRemoteResourceObject::CacheUpdatedCallback onCacheUpdated)
+            const RCSResourceAttributes& data, int eCode,
+            RCSRemoteResourceObject::CacheUpdatedCallback onCacheUpdated,
+            std::weak_ptr<RCSRemoteResourceObject> resourcePtr)
     {
         SCOPE_LOG_F(DEBUG, TAG);
 
-        onCacheUpdated(data);
+        //If error code is failure then RE Cache module should
+        //do clean up for caching flags, maps etc.
+        if(eCode > 4)
+        {
+            OIC_LOG_V(ERROR, TAG, "Error code: %d",eCode);
+            try
+            {
+                std::shared_ptr<RCSRemoteResourceObject> resource = resourcePtr.lock();
+                if(resource)
+                {
+                    resource->stopCaching();
+                }
+                else
+                {
+                    OIC_LOG(ERROR, TAG, "Resource object is null");
+                }
+            }
+            catch(...)
+            {
+                //Exception will be thrown: stack will return OC_STACK_ERROR
+                // if it already stopped observe. This call is reqired for clearing
+                //Cache manager.
+                OIC_LOG(DEBUG, TAG, "Cleared Cache");
+            }
+        }
+
+        //Calling application callback
+        onCacheUpdated(data, eCode);
         return OC_STACK_OK;
     }
 
-    void setCallback(const HeaderOptions&, const ResponseStatement& response, int,
+    void setRemoteAttributesCb(const HeaderOptions&, const ResponseStatement& response, int eCode,
             RCSRemoteResourceObject::RemoteAttributesSetCallback onRemoteAttributesSet)
     {
         SCOPE_LOG_F(DEBUG, TAG);
 
-        onRemoteAttributesSet(response.getAttributes());
+        onRemoteAttributesSet(response.getAttributes(), eCode);
     }
 
-    void getCallback(const HeaderOptions&, const ResponseStatement& response, int,
+    void getRemoteAttributesCb(const HeaderOptions&, const ResponseStatement& response, int eCode,
             RCSRemoteResourceObject::RemoteAttributesGetCallback onRemoteAttributesReceived)
     {
         SCOPE_LOG_F(DEBUG, TAG);
 
-        onRemoteAttributesReceived(response.getAttributes());
+        onRemoteAttributesReceived(response.getAttributes(), eCode);
     }
 }
 
@@ -120,9 +150,55 @@ namespace OIC
 {
     namespace Service
     {
+
+        RCSQueryParams& RCSQueryParams::setResourceInterface(std::string resourceInterface)
+        {
+            m_resourceInterface = std::move(resourceInterface);
+            return *this;
+        }
+
+        RCSQueryParams& RCSQueryParams::setResourceType(std::string resourceType)
+        {
+            m_resourceType = std::move(resourceType);
+            return *this;
+        }
+
+        RCSQueryParams& RCSQueryParams::put(std::string key, std::string value)
+        {
+            m_map[std::move(key)] = std::move(value);
+            return *this;
+        }
+
+        std::string RCSQueryParams::getResourceInterface() const
+        {
+            return m_resourceInterface;
+        }
+
+        std::string RCSQueryParams::getResourceType() const
+        {
+            return m_resourceType;
+        }
+
+        std::string RCSQueryParams::get(const std::string& key) const
+        {
+            try
+            {
+                return m_map.at(key);
+            }
+            catch (const std::out_of_range&)
+            {
+                throw RCSInvalidKeyException(key + " is an invalid key");
+            }
+        }
+
+        const RCSQueryParams::Map& RCSQueryParams::getAll() const
+        {
+            return m_map;
+        }
+
         RCSRemoteResourceObject::RCSRemoteResourceObject(
-                std::shared_ptr< PrimitiveResource > pResource) :
-                m_primitiveResource{ pResource },
+                std::shared_ptr< PrimitiveResource > primtiveResource) :
+                m_primitiveResource{ primtiveResource },
                 m_cacheId{ },
                 m_brokerId{ }
         {
@@ -132,8 +208,43 @@ namespace OIC
         {
             SCOPE_LOG_F(DEBUG, TAG);
 
-            stopCaching();
-            stopMonitoring();
+            try{
+                stopCaching();
+                stopMonitoring();
+            }
+            catch(std::exception &e){
+                OIC_LOG_V(ERROR, TAG, "%s", e.what());
+            }
+        }
+
+        RCSRemoteResourceObject::Ptr RCSRemoteResourceObject::fromOCResource(
+                std::shared_ptr< OC::OCResource > ocResource)
+        {
+            if (!ocResource)
+            {
+                throw RCSInvalidParameterException("the oc resource must not be nullptr.");
+            }
+
+            return std::make_shared< RCSRemoteResourceObject >(
+                    PrimitiveResource::create(ocResource));
+        }
+
+        std::shared_ptr< OC::OCResource > RCSRemoteResourceObject::toOCResource(
+        RCSRemoteResourceObject::Ptr rcsResource)
+        {
+            if (!rcsResource)
+            {
+                throw RCSInvalidParameterException("the rcs resource must not be nullptr.");
+            }
+
+            OC::OCResource::Ptr ocResource = OC::OCPlatform::constructResourceObject(rcsResource->getAddress(),
+                rcsResource->getUri(),
+                rcsResource->m_primitiveResource->getConnectivityType(),
+                rcsResource->isObservable(),
+                rcsResource->getTypes(),
+                rcsResource->getInterfaces());
+
+            return ocResource;
         }
 
         bool RCSRemoteResourceObject::isMonitoring() const
@@ -157,13 +268,13 @@ namespace OIC
 
             if (!cb)
             {
-                throw InvalidParameterException{ "startMonitoring : Callback is NULL" };
+                throw RCSInvalidParameterException{ "startMonitoring : Callback is NULL" };
             }
 
             if (isMonitoring())
             {
-                OC_LOG(DEBUG, TAG, "startMonitoring : already started");
-                throw BadRequestException{ "Monitoring already started." };
+                OIC_LOG(DEBUG, TAG, "startMonitoring : already started");
+                throw RCSBadRequestException{ "Monitoring already started." };
             }
 
             m_brokerId = ResourceBroker::getInstance()->hostResource(m_primitiveResource,
@@ -176,7 +287,7 @@ namespace OIC
 
             if (!isMonitoring())
             {
-                OC_LOG(DEBUG, TAG, "stopMonitoring : Not started");
+                OIC_LOG(DEBUG, TAG, "stopMonitoring : Not started");
                 return;
             }
 
@@ -202,30 +313,43 @@ namespace OIC
             startCaching({ });
         }
 
-        void RCSRemoteResourceObject::startCaching(CacheUpdatedCallback cb)
+        void RCSRemoteResourceObject::startCaching(CacheUpdatedCallback cb, CacheMode mode)
         {
             SCOPE_LOG_F(DEBUG, TAG);
 
             if (isCaching())
             {
-                OC_LOG(DEBUG, TAG, "startCaching : already Started");
-                throw BadRequestException{ "Caching already started." };
+                OIC_LOG(DEBUG, TAG, "startCaching : already Started");
+                throw RCSBadRequestException{ "Caching already started." };
+            }
+
+            if (mode == CacheMode::OBSERVE_ONLY)
+            {
+                m_cacheId = ResourceCacheManager::getInstance()->requestResourceCache(
+                        m_primitiveResource,
+                        std::bind(cachingCallback, std::placeholders::_1,
+                                  std::placeholders::_2, std::placeholders::_3,
+                                  std::move(cb), shared_from_this()), CACHE_METHOD::OBSERVE_ONLY,
+                                  REPORT_FREQUENCY::UPTODATE, 0);
             }
 
-            if (cb)
+            else if (cb)
             {
                 m_cacheId = ResourceCacheManager::getInstance()->requestResourceCache(
                         m_primitiveResource,
-                        std::bind(cachingCallback, std::placeholders::_1, std::placeholders::_2,
-                                std::move(cb)), REPORT_FREQUENCY::UPTODATE, 0);
+                        std::bind(cachingCallback, std::placeholders::_1,
+                                std::placeholders::_2, std::placeholders::_3,
+                                std::move(cb), shared_from_this()), CACHE_METHOD::ITERATED_GET,
+                                REPORT_FREQUENCY::UPTODATE, 0);
             }
             else
             {
                 m_cacheId = ResourceCacheManager::getInstance()->requestResourceCache(
-                        m_primitiveResource, { }, REPORT_FREQUENCY::NONE, 0);
+                        m_primitiveResource, { }, CACHE_METHOD::ITERATED_GET,
+                        REPORT_FREQUENCY::NONE, 0);
             }
 
-            OC_LOG_V(DEBUG, TAG, "startCaching CACHE ID %d", m_cacheId);
+            OIC_LOG_V(DEBUG, TAG, "startCaching CACHE ID %d", m_cacheId);
         }
 
         void RCSRemoteResourceObject::stopCaching()
@@ -234,11 +358,23 @@ namespace OIC
 
             if (!isCaching())
             {
-                OC_LOG(DEBUG, TAG, "Caching already terminated");
+                OIC_LOG(DEBUG, TAG, "Caching already terminated");
                 return;
             }
 
-            ResourceCacheManager::getInstance()->cancelResourceCache(m_cacheId);
+            try
+            {
+                ResourceCacheManager::getInstance()->cancelResourceCache(m_cacheId);
+            }
+            catch (const RCSInvalidParameterException &)
+            {
+                throw;
+            }
+            catch (...)
+            {
+                m_cacheId = 0;
+                throw;
+            }
             m_cacheId = 0;
         }
 
@@ -252,7 +388,7 @@ namespace OIC
             }
 
             return convertCacheState(
-                    ResourceCacheManager::getInstance()->getResourceCacheState(m_primitiveResource));
+                    ResourceCacheManager::getInstance()->getResourceCacheState(m_cacheId));
         }
 
         bool RCSRemoteResourceObject::isCachedAvailable() const
@@ -271,15 +407,15 @@ namespace OIC
 
             if (!isCaching())
             {
-                throw BadRequestException{ "Caching not started." };
+                throw RCSBadRequestException{ "Caching not started." };
             }
 
             if (!isCachedAvailable())
             {
-                throw BadRequestException{ "Cache data is not available." };
+                throw RCSBadRequestException{ "Cache data is not available." };
             }
 
-            return ResourceCacheManager::getInstance()->getCachedData(m_primitiveResource);
+            return ResourceCacheManager::getInstance()->getCachedData(m_cacheId);
         }
 
         RCSResourceAttributes::Value RCSRemoteResourceObject::getCachedAttribute(
@@ -287,16 +423,7 @@ namespace OIC
         {
             SCOPE_LOG_F(DEBUG, TAG);
 
-            //check whether key is available or not
-            RCSResourceAttributes cachedAttributes= getCachedAttributes();
-            if(cachedAttributes.contains(key))
-            {
-                return getCachedAttributes().at(key);
-            }
-            else
-            {
-                throw BadRequestException{ "Requested Attribute is not present" };
-            }
+            return getCachedAttributes().at(key);
         }
 
         std::string RCSRemoteResourceObject::getUri() const
@@ -325,14 +452,43 @@ namespace OIC
 
             if (!cb)
             {
-                throw InvalidParameterException{ "getRemoteAttributes : Callback is empty" };
+                throw RCSInvalidParameterException{ "getRemoteAttributes : Callback is empty" };
             }
 
             m_primitiveResource->requestGet(
-                    std::bind(getCallback, std::placeholders::_1, std::placeholders::_2,
+                    std::bind(getRemoteAttributesCb, std::placeholders::_1, std::placeholders::_2,
                             std::placeholders::_3, std::move(cb)));
         }
 
+        void RCSRemoteResourceObject::get(GetCallback cb)
+        {
+            SCOPE_LOG_F(DEBUG, TAG);
+
+            if (!cb)
+            {
+                throw RCSInvalidParameterException{ "get : Callback is empty" };
+            }
+
+            m_primitiveResource->requestGet(std::move(cb));
+        }
+
+        void RCSRemoteResourceObject::get(const RCSQueryParams& queryParams, GetCallback cb)
+        {
+            SCOPE_LOG_F(DEBUG, TAG);
+
+            if (!cb)
+            {
+                throw RCSInvalidParameterException{ "get : Callback is empty" };
+            }
+
+            const auto& paramMap = queryParams.getAll();
+
+            m_primitiveResource->requestGetWith(
+                    queryParams.getResourceType(), queryParams.getResourceInterface(),
+                    OC::QueryParamsMap{ paramMap.begin(), paramMap.end() },
+                    std::move(cb));
+        }
+
         void RCSRemoteResourceObject::setRemoteAttributes(const RCSResourceAttributes& attribute,
                 RemoteAttributesSetCallback cb)
         {
@@ -340,12 +496,61 @@ namespace OIC
 
             if (!cb)
             {
-                throw InvalidParameterException{ "setRemoteAttributes : Callback is empty" };
+                throw RCSInvalidParameterException{ "setRemoteAttributes : Callback is empty" };
             }
 
             m_primitiveResource->requestSet(attribute,
-                    std::bind(setCallback, std::placeholders::_1, std::placeholders::_2,
+                    std::bind(setRemoteAttributesCb, std::placeholders::_1, std::placeholders::_2,
                             std::placeholders::_3, cb));
         }
+
+        void RCSRemoteResourceObject::set(const RCSResourceAttributes& attributes, SetCallback cb)
+        {
+            SCOPE_LOG_F(DEBUG, TAG);
+
+            if (!cb)
+            {
+                throw RCSInvalidParameterException{ "set : Callback is empty" };
+            }
+
+            m_primitiveResource->requestSet(attributes, std::move(cb));
+        }
+
+        void RCSRemoteResourceObject::set(const RCSQueryParams& queryParams,
+                const RCSResourceAttributes& attributes, SetCallback cb)
+        {
+            SCOPE_LOG_F(DEBUG, TAG);
+
+            if (!cb)
+            {
+                throw RCSInvalidParameterException{ "set : Callback is empty" };
+            }
+
+            const auto& paramMap = queryParams.getAll();
+
+            m_primitiveResource->requestSetWith(
+                    queryParams.getResourceType(), queryParams.getResourceInterface(),
+                    OC::QueryParamsMap{ paramMap.begin(), paramMap.end() }, attributes,
+                    std::move(cb));
+        }
+
+        void RCSRemoteResourceObject::set(const RCSQueryParams& queryParams,
+                const RCSRepresentation& rep, SetCallback cb)
+        {
+            SCOPE_LOG_F(DEBUG, TAG);
+
+            if (!cb)
+            {
+                throw RCSInvalidParameterException{ "set : Callback is empty" };
+            }
+
+            const auto& paramMap = queryParams.getAll();
+
+            m_primitiveResource->requestSetWith(
+                    queryParams.getResourceType(), queryParams.getResourceInterface(),
+                    OC::QueryParamsMap{ paramMap.begin(), paramMap.end() }, rep,
+                    std::move(cb));
+        }
+
     }
 }