replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / service / resource-encapsulation / src / resourceClient / RCSRemoteResourceObject.cpp
1 //******************************************************************
2 //
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #include "RCSRemoteResourceObject.h"
22
23 #include "OCPlatform.h"
24
25 #include "ResourceBroker.h"
26 #include "ResourceCacheManager.h"
27
28 #include "ScopeLogger.h"
29
30 #define TAG PCF("RCSRemoteResourceObject")
31
32 namespace
33 {
34     using namespace OIC::Service;
35
36     ResourceState convertBrokerState(BROKER_STATE state)
37     {
38         SCOPE_LOG_F(DEBUG, TAG);
39
40         switch (state)
41         {
42             case BROKER_STATE::ALIVE:
43                 return ResourceState::ALIVE;
44
45             case BROKER_STATE::REQUESTED:
46                 return ResourceState::REQUESTED;
47
48             case BROKER_STATE::LOST_SIGNAL:
49                 return ResourceState::LOST_SIGNAL;
50
51             case BROKER_STATE::DESTROYED:
52                 return ResourceState::DESTROYED;
53
54             case BROKER_STATE::NONE:
55                 return ResourceState::NONE;
56         }
57
58         return ResourceState::NONE;
59     }
60
61     CacheState convertCacheState(CACHE_STATE state)
62     {
63         SCOPE_LOG_F(DEBUG, TAG);
64
65         switch (state)
66         {
67             case CACHE_STATE::READY:
68                 return CacheState::READY;
69
70             case CACHE_STATE::READY_YET:
71             case CACHE_STATE::UPDATING:
72                 return CacheState::UNREADY;
73
74             case CACHE_STATE::LOST_SIGNAL:
75                 return CacheState::LOST_SIGNAL;
76
77             case CACHE_STATE::DESTROYED:
78             case CACHE_STATE::NONE:
79                 return CacheState::NONE;
80         }
81
82         return CacheState::NONE;
83     }
84
85     OCStackResult hostingCallback(BROKER_STATE state,
86             RCSRemoteResourceObject::StateChangedCallback onResourceStateChanged)
87     {
88         SCOPE_LOG_F(DEBUG, TAG);
89
90         onResourceStateChanged(convertBrokerState(state));
91         return OC_STACK_OK;
92     }
93
94     OCStackResult cachingCallback(std::shared_ptr< PrimitiveResource >,
95             const RCSResourceAttributes& data, int eCode,
96             RCSRemoteResourceObject::CacheUpdatedCallback onCacheUpdated,
97             std::weak_ptr<RCSRemoteResourceObject> resourcePtr)
98     {
99         SCOPE_LOG_F(DEBUG, TAG);
100
101         //If error code is failure then RE Cache module should
102         //do clean up for caching flags, maps etc.
103         if(eCode > 4)
104         {
105             OIC_LOG_V(ERROR, TAG, "Error code: %d",eCode);
106             try
107             {
108                 std::shared_ptr<RCSRemoteResourceObject> resource = resourcePtr.lock();
109                 if(resource)
110                 {
111                     resource->stopCaching();
112                 }
113                 else
114                 {
115                     OIC_LOG(ERROR, TAG, "Resource object is null");
116                 }
117             }
118             catch(...)
119             {
120                 //Exception will be thrown: stack will return OC_STACK_ERROR
121                 // if it already stopped observe. This call is reqired for clearing
122                 //Cache manager.
123                 OIC_LOG(DEBUG, TAG, "Cleared Cache");
124             }
125         }
126
127         //Calling application callback
128         onCacheUpdated(data, eCode);
129         return OC_STACK_OK;
130     }
131
132     void setRemoteAttributesCb(const HeaderOptions&, const ResponseStatement& response, int eCode,
133             RCSRemoteResourceObject::RemoteAttributesSetCallback onRemoteAttributesSet)
134     {
135         SCOPE_LOG_F(DEBUG, TAG);
136
137         onRemoteAttributesSet(response.getAttributes(), eCode);
138     }
139
140     void getRemoteAttributesCb(const HeaderOptions&, const ResponseStatement& response, int eCode,
141             RCSRemoteResourceObject::RemoteAttributesGetCallback onRemoteAttributesReceived)
142     {
143         SCOPE_LOG_F(DEBUG, TAG);
144
145         onRemoteAttributesReceived(response.getAttributes(), eCode);
146     }
147 }
148
149 namespace OIC
150 {
151     namespace Service
152     {
153
154         RCSQueryParams& RCSQueryParams::setResourceInterface(std::string resourceInterface)
155         {
156             m_resourceInterface = std::move(resourceInterface);
157             return *this;
158         }
159
160         RCSQueryParams& RCSQueryParams::setResourceType(std::string resourceType)
161         {
162             m_resourceType = std::move(resourceType);
163             return *this;
164         }
165
166         RCSQueryParams& RCSQueryParams::put(std::string key, std::string value)
167         {
168             m_map[std::move(key)] = std::move(value);
169             return *this;
170         }
171
172         std::string RCSQueryParams::getResourceInterface() const
173         {
174             return m_resourceInterface;
175         }
176
177         std::string RCSQueryParams::getResourceType() const
178         {
179             return m_resourceType;
180         }
181
182         std::string RCSQueryParams::get(const std::string& key) const
183         {
184             try
185             {
186                 return m_map.at(key);
187             }
188             catch (const std::out_of_range&)
189             {
190                 throw RCSInvalidKeyException(key + " is an invalid key");
191             }
192         }
193
194         const RCSQueryParams::Map& RCSQueryParams::getAll() const
195         {
196             return m_map;
197         }
198
199         RCSRemoteResourceObject::RCSRemoteResourceObject(
200                 std::shared_ptr< PrimitiveResource > primtiveResource) :
201                 m_primitiveResource{ primtiveResource },
202                 m_cacheId{ },
203                 m_brokerId{ }
204         {
205         }
206
207         RCSRemoteResourceObject::~RCSRemoteResourceObject()
208         {
209             SCOPE_LOG_F(DEBUG, TAG);
210
211             try{
212                 stopCaching();
213                 stopMonitoring();
214             }
215             catch(std::exception &e){
216                 OIC_LOG_V(ERROR, TAG, "%s", e.what());
217             }
218         }
219
220         RCSRemoteResourceObject::Ptr RCSRemoteResourceObject::fromOCResource(
221                 std::shared_ptr< OC::OCResource > ocResource)
222         {
223             if (!ocResource)
224             {
225                 throw RCSInvalidParameterException("the oc resource must not be nullptr.");
226             }
227
228             return std::make_shared< RCSRemoteResourceObject >(
229                     PrimitiveResource::create(ocResource));
230         }
231
232         std::shared_ptr< OC::OCResource > RCSRemoteResourceObject::toOCResource(
233         RCSRemoteResourceObject::Ptr rcsResource)
234         {
235             if (!rcsResource)
236             {
237                 throw RCSInvalidParameterException("the rcs resource must not be nullptr.");
238             }
239
240             OC::OCResource::Ptr ocResource = OC::OCPlatform::constructResourceObject(rcsResource->getAddress(),
241                 rcsResource->getUri(),
242                 rcsResource->m_primitiveResource->getConnectivityType(),
243                 rcsResource->isObservable(),
244                 rcsResource->getTypes(),
245                 rcsResource->getInterfaces());
246
247             return ocResource;
248         }
249
250         bool RCSRemoteResourceObject::isMonitoring() const
251         {
252             return m_brokerId != 0;
253         }
254
255         bool RCSRemoteResourceObject::isCaching() const
256         {
257             return m_cacheId != 0;
258         }
259
260         bool RCSRemoteResourceObject::isObservable() const
261         {
262             return m_primitiveResource->isObservable();
263         }
264
265         void RCSRemoteResourceObject::startMonitoring(StateChangedCallback cb)
266         {
267             SCOPE_LOG_F(DEBUG, TAG);
268
269             if (!cb)
270             {
271                 throw RCSInvalidParameterException{ "startMonitoring : Callback is NULL" };
272             }
273
274             if (isMonitoring())
275             {
276                 OIC_LOG(DEBUG, TAG, "startMonitoring : already started");
277                 throw RCSBadRequestException{ "Monitoring already started." };
278             }
279
280             m_brokerId = ResourceBroker::getInstance()->hostResource(m_primitiveResource,
281                     std::bind(hostingCallback, std::placeholders::_1, std::move(cb)));
282         }
283
284         void RCSRemoteResourceObject::stopMonitoring()
285         {
286             SCOPE_LOG_F(DEBUG, TAG);
287
288             if (!isMonitoring())
289             {
290                 OIC_LOG(DEBUG, TAG, "stopMonitoring : Not started");
291                 return;
292             }
293
294             ResourceBroker::getInstance()->cancelHostResource(m_brokerId);
295             m_brokerId = 0;
296         }
297
298         ResourceState RCSRemoteResourceObject::getState() const
299         {
300             SCOPE_LOG_F(DEBUG, TAG);
301
302             if (!isMonitoring())
303             {
304                 return ResourceState::NONE;
305             }
306
307             return convertBrokerState(
308                     ResourceBroker::getInstance()->getResourceState(m_primitiveResource));
309         }
310
311         void RCSRemoteResourceObject::startCaching()
312         {
313             startCaching({ });
314         }
315
316         void RCSRemoteResourceObject::startCaching(CacheUpdatedCallback cb, CacheMode mode)
317         {
318             SCOPE_LOG_F(DEBUG, TAG);
319
320             if (isCaching())
321             {
322                 OIC_LOG(DEBUG, TAG, "startCaching : already Started");
323                 throw RCSBadRequestException{ "Caching already started." };
324             }
325
326             if (mode == CacheMode::OBSERVE_ONLY)
327             {
328                 m_cacheId = ResourceCacheManager::getInstance()->requestResourceCache(
329                         m_primitiveResource,
330                         std::bind(cachingCallback, std::placeholders::_1,
331                                   std::placeholders::_2, std::placeholders::_3,
332                                   std::move(cb), shared_from_this()), CACHE_METHOD::OBSERVE_ONLY,
333                                   REPORT_FREQUENCY::UPTODATE, 0);
334             }
335
336             else if (cb)
337             {
338                 m_cacheId = ResourceCacheManager::getInstance()->requestResourceCache(
339                         m_primitiveResource,
340                         std::bind(cachingCallback, std::placeholders::_1,
341                                 std::placeholders::_2, std::placeholders::_3,
342                                 std::move(cb), shared_from_this()), CACHE_METHOD::ITERATED_GET,
343                                 REPORT_FREQUENCY::UPTODATE, 0);
344             }
345             else
346             {
347                 m_cacheId = ResourceCacheManager::getInstance()->requestResourceCache(
348                         m_primitiveResource, { }, CACHE_METHOD::ITERATED_GET,
349                         REPORT_FREQUENCY::NONE, 0);
350             }
351
352             OIC_LOG_V(DEBUG, TAG, "startCaching CACHE ID %d", m_cacheId);
353         }
354
355         void RCSRemoteResourceObject::stopCaching()
356         {
357             SCOPE_LOG_F(DEBUG, TAG);
358
359             if (!isCaching())
360             {
361                 OIC_LOG(DEBUG, TAG, "Caching already terminated");
362                 return;
363             }
364
365             try
366             {
367                 ResourceCacheManager::getInstance()->cancelResourceCache(m_cacheId);
368             }
369             catch (const RCSInvalidParameterException &)
370             {
371                 throw;
372             }
373             catch (...)
374             {
375                 m_cacheId = 0;
376                 throw;
377             }
378             m_cacheId = 0;
379         }
380
381         CacheState RCSRemoteResourceObject::getCacheState() const
382         {
383             SCOPE_LOG_F(DEBUG, TAG);
384
385             if (!isCaching())
386             {
387                 return CacheState::NONE;
388             }
389
390             return convertCacheState(
391                     ResourceCacheManager::getInstance()->getResourceCacheState(m_cacheId));
392         }
393
394         bool RCSRemoteResourceObject::isCachedAvailable() const
395         {
396             if (!isCaching())
397             {
398                 return false;
399             }
400
401             return ResourceCacheManager::getInstance()->isCachedData(m_cacheId);
402         }
403
404         RCSResourceAttributes RCSRemoteResourceObject::getCachedAttributes() const
405         {
406             SCOPE_LOG_F(DEBUG, TAG);
407
408             if (!isCaching())
409             {
410                 throw RCSBadRequestException{ "Caching not started." };
411             }
412
413             if (!isCachedAvailable())
414             {
415                 throw RCSBadRequestException{ "Cache data is not available." };
416             }
417
418             return ResourceCacheManager::getInstance()->getCachedData(m_cacheId);
419         }
420
421         RCSResourceAttributes::Value RCSRemoteResourceObject::getCachedAttribute(
422                 const std::string& key) const
423         {
424             SCOPE_LOG_F(DEBUG, TAG);
425
426             return getCachedAttributes().at(key);
427         }
428
429         std::string RCSRemoteResourceObject::getUri() const
430         {
431             return m_primitiveResource->getUri();
432         }
433
434         std::string RCSRemoteResourceObject::getAddress() const
435         {
436             return m_primitiveResource->getHost();
437         }
438
439         std::vector< std::string > RCSRemoteResourceObject::getTypes() const
440         {
441             return m_primitiveResource->getTypes();
442         }
443
444         std::vector< std::string > RCSRemoteResourceObject::getInterfaces() const
445         {
446             return m_primitiveResource->getInterfaces();
447         }
448
449         void RCSRemoteResourceObject::getRemoteAttributes(RemoteAttributesGetCallback cb)
450         {
451             SCOPE_LOG_F(DEBUG, TAG);
452
453             if (!cb)
454             {
455                 throw RCSInvalidParameterException{ "getRemoteAttributes : Callback is empty" };
456             }
457
458             m_primitiveResource->requestGet(
459                     std::bind(getRemoteAttributesCb, std::placeholders::_1, std::placeholders::_2,
460                             std::placeholders::_3, std::move(cb)));
461         }
462
463         void RCSRemoteResourceObject::get(GetCallback cb)
464         {
465             SCOPE_LOG_F(DEBUG, TAG);
466
467             if (!cb)
468             {
469                 throw RCSInvalidParameterException{ "get : Callback is empty" };
470             }
471
472             m_primitiveResource->requestGet(std::move(cb));
473         }
474
475         void RCSRemoteResourceObject::get(const RCSQueryParams& queryParams, GetCallback cb)
476         {
477             SCOPE_LOG_F(DEBUG, TAG);
478
479             if (!cb)
480             {
481                 throw RCSInvalidParameterException{ "get : Callback is empty" };
482             }
483
484             const auto& paramMap = queryParams.getAll();
485
486             m_primitiveResource->requestGetWith(
487                     queryParams.getResourceType(), queryParams.getResourceInterface(),
488                     OC::QueryParamsMap{ paramMap.begin(), paramMap.end() },
489                     std::move(cb));
490         }
491
492         void RCSRemoteResourceObject::setRemoteAttributes(const RCSResourceAttributes& attribute,
493                 RemoteAttributesSetCallback cb)
494         {
495             SCOPE_LOG_F(DEBUG, TAG);
496
497             if (!cb)
498             {
499                 throw RCSInvalidParameterException{ "setRemoteAttributes : Callback is empty" };
500             }
501
502             m_primitiveResource->requestSet(attribute,
503                     std::bind(setRemoteAttributesCb, std::placeholders::_1, std::placeholders::_2,
504                             std::placeholders::_3, cb));
505         }
506
507         void RCSRemoteResourceObject::set(const RCSResourceAttributes& attributes, SetCallback cb)
508         {
509             SCOPE_LOG_F(DEBUG, TAG);
510
511             if (!cb)
512             {
513                 throw RCSInvalidParameterException{ "set : Callback is empty" };
514             }
515
516             m_primitiveResource->requestSet(attributes, std::move(cb));
517         }
518
519         void RCSRemoteResourceObject::set(const RCSQueryParams& queryParams,
520                 const RCSResourceAttributes& attributes, SetCallback cb)
521         {
522             SCOPE_LOG_F(DEBUG, TAG);
523
524             if (!cb)
525             {
526                 throw RCSInvalidParameterException{ "set : Callback is empty" };
527             }
528
529             const auto& paramMap = queryParams.getAll();
530
531             m_primitiveResource->requestSetWith(
532                     queryParams.getResourceType(), queryParams.getResourceInterface(),
533                     OC::QueryParamsMap{ paramMap.begin(), paramMap.end() }, attributes,
534                     std::move(cb));
535         }
536
537         void RCSRemoteResourceObject::set(const RCSQueryParams& queryParams,
538                 const RCSRepresentation& rep, SetCallback cb)
539         {
540             SCOPE_LOG_F(DEBUG, TAG);
541
542             if (!cb)
543             {
544                 throw RCSInvalidParameterException{ "set : Callback is empty" };
545             }
546
547             const auto& paramMap = queryParams.getAll();
548
549             m_primitiveResource->requestSetWith(
550                     queryParams.getResourceType(), queryParams.getResourceInterface(),
551                     OC::QueryParamsMap{ paramMap.begin(), paramMap.end() }, rep,
552                     std::move(cb));
553         }
554
555     }
556 }