Imported Upstream version 1.1.0
[platform/upstream/iotivity.git] / service / resource-hosting / src / HostingObject.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 "HostingObject.h"
22
23 #include "RCSSeparateResponse.h"
24 #include "RequestObject.h"
25
26 namespace OIC
27 {
28     namespace Service
29     {
30
31         namespace
32         {
33             const auto sizeofHostingTag = strlen("/hosting");
34         }
35
36         HostingObject::HostingObject()
37         : remoteObject(nullptr), mirroredServer(nullptr),
38           pDataUpdateCB(nullptr), pDestroyCB(nullptr)
39         {
40         }
41
42         HostingObject::~HostingObject()
43         {
44             pDataUpdateCB = {};
45
46             if (remoteObject)
47             {
48                 remoteObject->stopMonitoring();
49                 remoteObject->stopCaching();
50             }
51         }
52
53         auto HostingObject::getRemoteResource() const -> RemoteObjectPtr
54         {
55             return remoteObject;
56         }
57
58         auto HostingObject::createHostingObject(const RemoteObjectPtr & rResource,
59                 DestroyedCallback destroyCB) -> Ptr
60         {
61             auto newObject = std::make_shared<HostingObject>();
62
63             newObject->remoteObject = rResource;
64             newObject->pDestroyCB = destroyCB;
65
66             newObject->pDataUpdateCB = std::bind(&HostingObject::dataChangedCB, newObject,
67                     std::placeholders::_1);
68
69             newObject->remoteObject->startMonitoring(
70                     std::bind(&HostingObject::stateChangedCB, newObject,
71                             std::placeholders::_1));
72             newObject->remoteObject->startCaching(newObject->pDataUpdateCB);
73
74             return newObject;
75         }
76
77         void HostingObject::destroyHostingObject()
78         {
79             if (pDestroyCB) pDestroyCB();
80         }
81
82         void HostingObject::stateChangedCB(ResourceState state)
83         {
84             switch (state)
85             {
86             case ResourceState::ALIVE:
87             {
88                 if (!this->remoteObject->isCaching())
89                 {
90                     try
91                     {
92                         this->remoteObject->startCaching(pDataUpdateCB);
93                     } catch (const RCSException & e)
94                     {
95                         OIC_HOSTING_LOG(DEBUG,
96                                 "[HostingObject::stateChangedCB]startCaching InvalidParameterException:%s",
97                                 e.what());
98                     }
99                 }
100                 break;
101             }
102             case ResourceState::LOST_SIGNAL:
103             case ResourceState::DESTROYED:
104             {
105                 try
106                 {
107                     this->remoteObject->stopCaching();
108                     this->remoteObject->stopMonitoring();
109                 } catch (const RCSException & e)
110                 {
111                     OIC_HOSTING_LOG(DEBUG,
112                             "[HostingObject::stateChangedCB]stopWatching InvalidParameterException:%s",
113                             e.what());
114                 }
115                 mirroredServer.reset();
116                 destroyHostingObject();
117                 break;
118             }
119             default:
120                 // not support of state
121                 break;
122             }
123         }
124
125         void HostingObject::dataChangedCB(const RCSResourceAttributes & attributes)
126         {
127             if (attributes.empty())
128             {
129                 return;
130             }
131
132             std::unique_lock<std::mutex> lock(mutexForCB);
133             if (mirroredServer == nullptr)
134             {
135                 try
136                 {
137                     mirroredServer = createMirroredServer(this->remoteObject);
138                 } catch (const RCSException & e)
139                 {
140                     OIC_HOSTING_LOG(DEBUG,
141                                 "[HostingObject::dataChangedCB]createMirroredServer Exception:%s",
142                                 e.what());
143                     return;
144                 }
145             }
146             lock.unlock();
147
148             RCSResourceObject::LockGuard guard(mirroredServer);
149             mirroredServer->getAttributes() = std::move(attributes);
150         }
151
152         auto HostingObject::createMirroredServer(RemoteObjectPtr rObject) -> ResourceObjectPtr
153         {
154             if (rObject == nullptr)
155             {
156                 throw RCSPlatformException(OC_STACK_ERROR);
157             }
158
159             std::string fulluri = rObject->getUri();
160             std::string uri = fulluri.substr(0, fulluri.size() - sizeofHostingTag);
161             std::vector<std::string> types = rObject->getTypes();
162             std::vector<std::string> interfaces = rObject->getInterfaces();
163             try
164             {
165                 auto resourceBuild = RCSResourceObject::Builder(uri, types[0], interfaces[0]);
166                 for (unsigned int i = 1; i < types.size(); ++i)
167                 {
168                     resourceBuild.addType(types[i]);
169                 }
170                 for (unsigned int i = 1; i < interfaces.size(); ++i)
171                 {
172                     resourceBuild.addInterface(interfaces[i]);
173                 }
174                 auto retResource = resourceBuild.build();
175
176                 retResource->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::UPDATED);
177                 retResource->setSetRequestHandler(
178                         std::bind(&HostingObject::setRequestHandler, this,
179                                 std::placeholders::_1, std::placeholders::_2));
180                 return retResource;
181             } catch (...)
182             {
183                 OIC_HOSTING_LOG(DEBUG, "[HostingObject::createMirroredServer] %s", "Exception");
184                 throw;
185             }
186         }
187
188         RCSSetResponse HostingObject::setRequestHandler(const RCSRequest & primitiveRequest,
189                     RCSResourceAttributes & resourceAttibutes)
190         {
191             try
192             {
193                 RequestObject::invokeRequest(getRemoteResource(),
194                         primitiveRequest, RequestObject::RequestMethod::Set, resourceAttibutes);
195
196             } catch (const RCSPlatformException & e)
197             {
198                 OIC_HOSTING_LOG(DEBUG,
199                         "[HostingObject::setRequestHandler] PlatformException:%s",
200                         e.what());
201                 throw;
202             }
203
204             return RCSSetResponse::separate();
205         }
206
207     } /* namespace Service */
208 } /* namespace OIC */