e90926179d224468a80fe08cae012a42fc1ef0b7
[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,
96             RCSRemoteResourceObject::CacheUpdatedCallback onCacheUpdated)
97     {
98         SCOPE_LOG_F(DEBUG, TAG);
99
100         onCacheUpdated(data);
101         return OC_STACK_OK;
102     }
103
104     void setRemoteAttributesCb(const HeaderOptions&, const ResponseStatement& response, int eCode,
105             RCSRemoteResourceObject::RemoteAttributesSetCallback onRemoteAttributesSet)
106     {
107         SCOPE_LOG_F(DEBUG, TAG);
108
109         onRemoteAttributesSet(response.getAttributes(), eCode);
110     }
111
112     void getRemoteAttributesCb(const HeaderOptions&, const ResponseStatement& response, int eCode,
113             RCSRemoteResourceObject::RemoteAttributesGetCallback onRemoteAttributesReceived)
114     {
115         SCOPE_LOG_F(DEBUG, TAG);
116
117         onRemoteAttributesReceived(response.getAttributes(), eCode);
118     }
119 }
120
121 namespace OIC
122 {
123     namespace Service
124     {
125
126         RCSQueryParams& RCSQueryParams::setResourceInterface(std::string resourceInterface)
127         {
128             m_resourceInterface = std::move(resourceInterface);
129             return *this;
130         }
131
132         RCSQueryParams& RCSQueryParams::setResourceType(std::string resourceType)
133         {
134             m_resourceType = std::move(resourceType);
135             return *this;
136         }
137
138         RCSQueryParams& RCSQueryParams::put(std::string key, std::string value)
139         {
140             m_map[std::move(key)] = std::move(value);
141             return *this;
142         }
143
144         std::string RCSQueryParams::getResourceInterface() const
145         {
146             return m_resourceInterface;
147         }
148
149         std::string RCSQueryParams::getResourceType() const
150         {
151             return m_resourceType;
152         }
153
154         std::string RCSQueryParams::get(const std::string& key) const
155         {
156             try
157             {
158                 return m_map.at(key);
159             }
160             catch (const std::out_of_range&)
161             {
162                 throw RCSInvalidKeyException(key + " is an invalid key");
163             }
164         }
165
166         const RCSQueryParams::Map& RCSQueryParams::getAll() const
167         {
168             return m_map;
169         }
170
171         RCSRemoteResourceObject::RCSRemoteResourceObject(
172                 std::shared_ptr< PrimitiveResource > primtiveResource) :
173                 m_primitiveResource{ primtiveResource },
174                 m_cacheId{ },
175                 m_brokerId{ }
176         {
177         }
178
179         RCSRemoteResourceObject::~RCSRemoteResourceObject()
180         {
181             SCOPE_LOG_F(DEBUG, TAG);
182
183             try{
184                 stopCaching();
185                 stopMonitoring();
186             }
187             catch(std::exception &e){
188                 OIC_LOG_V(ERROR, TAG, "%s", e.what());
189             }
190         }
191
192         RCSRemoteResourceObject::Ptr RCSRemoteResourceObject::fromOCResource(
193                 std::shared_ptr< OC::OCResource > ocResource)
194         {
195             if (!ocResource)
196             {
197                 throw RCSInvalidParameterException("the oc resource must not be nullptr.");
198             }
199
200             return std::make_shared< RCSRemoteResourceObject >(
201                     PrimitiveResource::create(ocResource));
202         }
203
204         std::shared_ptr< OC::OCResource > RCSRemoteResourceObject::toOCResource(
205         RCSRemoteResourceObject::Ptr rcsResource)
206         {
207             if (!rcsResource)
208             {
209                 throw RCSInvalidParameterException("the rcs resource must not be nullptr.");
210             }
211
212             OC::OCResource::Ptr ocResource = OC::OCPlatform::constructResourceObject(rcsResource->getAddress(),
213                 rcsResource->getUri(),
214                 CT_DEFAULT,
215                 rcsResource->isObservable(),
216                 rcsResource->getTypes(),
217                 rcsResource->getInterfaces());
218
219             return ocResource;
220         }
221
222         bool RCSRemoteResourceObject::isMonitoring() const
223         {
224             return m_brokerId != 0;
225         }
226
227         bool RCSRemoteResourceObject::isCaching() const
228         {
229             return m_cacheId != 0;
230         }
231
232         bool RCSRemoteResourceObject::isObservable() const
233         {
234             return m_primitiveResource->isObservable();
235         }
236
237         void RCSRemoteResourceObject::startMonitoring(StateChangedCallback cb)
238         {
239             SCOPE_LOG_F(DEBUG, TAG);
240
241             if (!cb)
242             {
243                 throw RCSInvalidParameterException{ "startMonitoring : Callback is NULL" };
244             }
245
246             if (isMonitoring())
247             {
248                 OIC_LOG(DEBUG, TAG, "startMonitoring : already started");
249                 throw RCSBadRequestException{ "Monitoring already started." };
250             }
251
252             m_brokerId = ResourceBroker::getInstance()->hostResource(m_primitiveResource,
253                     std::bind(hostingCallback, std::placeholders::_1, std::move(cb)));
254         }
255
256         void RCSRemoteResourceObject::stopMonitoring()
257         {
258             SCOPE_LOG_F(DEBUG, TAG);
259
260             if (!isMonitoring())
261             {
262                 OIC_LOG(DEBUG, TAG, "stopMonitoring : Not started");
263                 return;
264             }
265
266             ResourceBroker::getInstance()->cancelHostResource(m_brokerId);
267             m_brokerId = 0;
268         }
269
270         ResourceState RCSRemoteResourceObject::getState() const
271         {
272             SCOPE_LOG_F(DEBUG, TAG);
273
274             if (!isMonitoring())
275             {
276                 return ResourceState::NONE;
277             }
278
279             return convertBrokerState(
280                     ResourceBroker::getInstance()->getResourceState(m_primitiveResource));
281         }
282
283         void RCSRemoteResourceObject::startCaching()
284         {
285             startCaching({ });
286         }
287
288         void RCSRemoteResourceObject::startCaching(CacheUpdatedCallback cb, CacheMode mode)
289         {
290             SCOPE_LOG_F(DEBUG, TAG);
291
292             if (isCaching())
293             {
294                 OIC_LOG(DEBUG, TAG, "startCaching : already Started");
295                 throw RCSBadRequestException{ "Caching already started." };
296             }
297
298             if (mode == CacheMode::OBSERVE_ONLY)
299             {
300                 m_cacheId = ResourceCacheManager::getInstance()->requestResourceCache(
301                         m_primitiveResource,
302                         std::bind(cachingCallback, std::placeholders::_1, std::placeholders::_2,
303                                   std::move(cb)), CACHE_METHOD::OBSERVE_ONLY,
304                                   REPORT_FREQUENCY::UPTODATE, 0);
305             }
306
307             else if (cb)
308             {
309                 m_cacheId = ResourceCacheManager::getInstance()->requestResourceCache(
310                         m_primitiveResource,
311                         std::bind(cachingCallback, std::placeholders::_1, std::placeholders::_2,
312                                 std::move(cb)), CACHE_METHOD::ITERATED_GET,
313                                 REPORT_FREQUENCY::UPTODATE, 0);
314             }
315             else
316             {
317                 m_cacheId = ResourceCacheManager::getInstance()->requestResourceCache(
318                         m_primitiveResource, { }, CACHE_METHOD::ITERATED_GET,
319                         REPORT_FREQUENCY::NONE, 0);
320             }
321
322             OIC_LOG_V(DEBUG, TAG, "startCaching CACHE ID %d", m_cacheId);
323         }
324
325         void RCSRemoteResourceObject::stopCaching()
326         {
327             SCOPE_LOG_F(DEBUG, TAG);
328
329             if (!isCaching())
330             {
331                 OIC_LOG(DEBUG, TAG, "Caching already terminated");
332                 return;
333             }
334
335             ResourceCacheManager::getInstance()->cancelResourceCache(m_cacheId);
336             m_cacheId = 0;
337         }
338
339         CacheState RCSRemoteResourceObject::getCacheState() const
340         {
341             SCOPE_LOG_F(DEBUG, TAG);
342
343             if (!isCaching())
344             {
345                 return CacheState::NONE;
346             }
347
348             return convertCacheState(
349                     ResourceCacheManager::getInstance()->getResourceCacheState(m_cacheId));
350         }
351
352         bool RCSRemoteResourceObject::isCachedAvailable() const
353         {
354             if (!isCaching())
355             {
356                 return false;
357             }
358
359             return ResourceCacheManager::getInstance()->isCachedData(m_cacheId);
360         }
361
362         RCSResourceAttributes RCSRemoteResourceObject::getCachedAttributes() const
363         {
364             SCOPE_LOG_F(DEBUG, TAG);
365
366             if (!isCaching())
367             {
368                 throw RCSBadRequestException{ "Caching not started." };
369             }
370
371             if (!isCachedAvailable())
372             {
373                 throw RCSBadRequestException{ "Cache data is not available." };
374             }
375
376             return ResourceCacheManager::getInstance()->getCachedData(m_cacheId);
377         }
378
379         RCSResourceAttributes::Value RCSRemoteResourceObject::getCachedAttribute(
380                 const std::string& key) const
381         {
382             SCOPE_LOG_F(DEBUG, TAG);
383
384             return getCachedAttributes().at(key);
385         }
386
387         std::string RCSRemoteResourceObject::getUri() const
388         {
389             return m_primitiveResource->getUri();
390         }
391
392         std::string RCSRemoteResourceObject::getAddress() const
393         {
394             return m_primitiveResource->getHost();
395         }
396
397         std::vector< std::string > RCSRemoteResourceObject::getTypes() const
398         {
399             return m_primitiveResource->getTypes();
400         }
401
402         std::vector< std::string > RCSRemoteResourceObject::getInterfaces() const
403         {
404             return m_primitiveResource->getInterfaces();
405         }
406
407         void RCSRemoteResourceObject::getRemoteAttributes(RemoteAttributesGetCallback cb)
408         {
409             SCOPE_LOG_F(DEBUG, TAG);
410
411             if (!cb)
412             {
413                 throw RCSInvalidParameterException{ "getRemoteAttributes : Callback is empty" };
414             }
415
416             m_primitiveResource->requestGet(
417                     std::bind(getRemoteAttributesCb, std::placeholders::_1, std::placeholders::_2,
418                             std::placeholders::_3, std::move(cb)));
419         }
420
421         void RCSRemoteResourceObject::get(GetCallback cb)
422         {
423             SCOPE_LOG_F(DEBUG, TAG);
424
425             if (!cb)
426             {
427                 throw RCSInvalidParameterException{ "get : Callback is empty" };
428             }
429
430             m_primitiveResource->requestGet(std::move(cb));
431         }
432
433         void RCSRemoteResourceObject::get(const RCSQueryParams& queryParams, GetCallback cb)
434         {
435             SCOPE_LOG_F(DEBUG, TAG);
436
437             if (!cb)
438             {
439                 throw RCSInvalidParameterException{ "get : Callback is empty" };
440             }
441
442             const auto& paramMap = queryParams.getAll();
443
444             m_primitiveResource->requestGetWith(
445                     queryParams.getResourceType(), queryParams.getResourceInterface(),
446                     OC::QueryParamsMap{ paramMap.begin(), paramMap.end() },
447                     std::move(cb));
448         }
449
450         void RCSRemoteResourceObject::setRemoteAttributes(const RCSResourceAttributes& attribute,
451                 RemoteAttributesSetCallback cb)
452         {
453             SCOPE_LOG_F(DEBUG, TAG);
454
455             if (!cb)
456             {
457                 throw RCSInvalidParameterException{ "setRemoteAttributes : Callback is empty" };
458             }
459
460             m_primitiveResource->requestSet(attribute,
461                     std::bind(setRemoteAttributesCb, std::placeholders::_1, std::placeholders::_2,
462                             std::placeholders::_3, cb));
463         }
464
465         void RCSRemoteResourceObject::set(const RCSResourceAttributes& attributes, SetCallback cb)
466         {
467             SCOPE_LOG_F(DEBUG, TAG);
468
469             if (!cb)
470             {
471                 throw RCSInvalidParameterException{ "set : Callback is empty" };
472             }
473
474             m_primitiveResource->requestSet(attributes, std::move(cb));
475         }
476
477         void RCSRemoteResourceObject::set(const RCSQueryParams& queryParams,
478                 const RCSResourceAttributes& attributes, SetCallback cb)
479         {
480             SCOPE_LOG_F(DEBUG, TAG);
481
482             if (!cb)
483             {
484                 throw RCSInvalidParameterException{ "set : Callback is empty" };
485             }
486
487             const auto& paramMap = queryParams.getAll();
488
489             m_primitiveResource->requestSetWith(
490                     queryParams.getResourceType(), queryParams.getResourceInterface(),
491                     OC::QueryParamsMap{ paramMap.begin(), paramMap.end() }, attributes,
492                     std::move(cb));
493         }
494
495         void RCSRemoteResourceObject::set(const RCSQueryParams& queryParams,
496                 const RCSRepresentation& rep, SetCallback cb)
497         {
498             SCOPE_LOG_F(DEBUG, TAG);
499
500             if (!cb)
501             {
502                 throw RCSInvalidParameterException{ "set : Callback is empty" };
503             }
504
505             const auto& paramMap = queryParams.getAll();
506
507             m_primitiveResource->requestSetWith(
508                     queryParams.getResourceType(), queryParams.getResourceInterface(),
509                     OC::QueryParamsMap{ paramMap.begin(), paramMap.end() }, rep,
510                     std::move(cb));
511         }
512
513     }
514 }