Imported Upstream version 1.0.1
[platform/upstream/iotivity.git] / service / simulator / src / client-controller / simulator_remote_resource_impl.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 "simulator_remote_resource_impl.h"
22 #include "request_model_builder.h"
23 #include "simulator_exceptions.h"
24 #include "logger.h"
25
26 #define TAG "SIMULATOR_REMOTE_RESOURCE"
27
28 SimulatorRemoteResourceImpl::SimulatorRemoteResourceImpl(std::shared_ptr<OC::OCResource>
29         &ocResource)
30     :   m_observeState(false),
31         m_getRequestSender(new GETRequestSender(ocResource)),
32         m_putRequestSender(new PUTRequestSender(ocResource)),
33         m_postRequestSender(new POSTRequestSender(ocResource)),
34         m_autoRequestGenMngr(nullptr),
35         m_ocResource(ocResource)
36 {
37     m_id = m_ocResource->sid().append(m_ocResource->uri());
38 }
39
40 std::string SimulatorRemoteResourceImpl::getURI() const
41 {
42     return m_ocResource->uri();
43 }
44
45 std::string SimulatorRemoteResourceImpl::getHost() const
46 {
47     return m_ocResource->host();
48 }
49
50 std::string SimulatorRemoteResourceImpl::getID() const
51 {
52     return m_id;
53 }
54
55 SimulatorConnectivityType SimulatorRemoteResourceImpl::getConnectivityType() const
56 {
57     return convertConnectivityType(m_ocResource->connectivityType());
58 }
59
60 std::vector < std::string > SimulatorRemoteResourceImpl::getResourceTypes() const
61 {
62     return m_ocResource->getResourceTypes();
63 }
64
65 std::vector < std::string > SimulatorRemoteResourceImpl::getResourceInterfaces() const
66 {
67     return m_ocResource->getResourceInterfaces();
68 }
69
70 bool SimulatorRemoteResourceImpl::isObservable() const
71 {
72     return m_ocResource->isObservable();
73 }
74
75 void SimulatorRemoteResourceImpl::observe(ObserveType type,
76         ObserveNotificationCallback callback)
77 {
78     if (!callback)
79     {
80         OC_LOG(ERROR, TAG, "Invalid callback!");
81         throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid callback!");
82     }
83
84     std::lock_guard<std::mutex> lock(m_observeMutex);
85     if (m_observeState)
86     {
87         OC_LOG(WARNING, TAG, "Resource already in observe state !");
88         throw SimulatorException(SIMULATOR_ERROR, "Resource is already being observed!");
89     }
90
91     OC::ObserveCallback observeCallback = [this, callback](const OC::HeaderOptions & headerOptions,
92                                           const OC::OCRepresentation & rep, const int errorCode,
93                                           const int sequenceNum)
94     {
95         // Convert OCRepresentation to SimulatorResourceModel
96         SimulatorResourceModelSP repModel = SimulatorResourceModel::create(rep);
97         callback(m_id, static_cast<SimulatorResult>(errorCode), repModel, sequenceNum);
98     };
99
100     OC::ObserveType observeType = OC::ObserveType::Observe;
101     if (type == ObserveType::OBSERVE_ALL)
102     {
103         observeType = OC::ObserveType::ObserveAll;
104     }
105
106     try
107     {
108         OCStackResult ocResult = m_ocResource->observe(observeType, OC::QueryParamsMap(), observeCallback);
109         if (OC_STACK_OK != ocResult)
110         {
111             throw SimulatorException(static_cast<SimulatorResult>(ocResult), OC::OCException::reason(ocResult));
112         }
113     }
114     catch (OC::OCException &e)
115     {
116         throw SimulatorException(static_cast<SimulatorResult>(e.code()), e.reason());
117     }
118
119     m_observeState = true;
120 }
121
122 void SimulatorRemoteResourceImpl::cancelObserve()
123 {
124     try
125     {
126         OCStackResult ocResult = m_ocResource->cancelObserve(OC::QualityOfService::HighQos);
127         if (OC_STACK_OK != ocResult)
128         {
129             throw SimulatorException(static_cast<SimulatorResult>(ocResult), OC::OCException::reason(ocResult));
130         }
131     }
132     catch (OC::OCException &e)
133     {
134         throw SimulatorException(static_cast<SimulatorResult>(e.code()), e.reason());
135     }
136
137     std::lock_guard<std::mutex> lock(m_observeMutex);
138     m_observeState = false;
139 }
140
141 void SimulatorRemoteResourceImpl::get(const std::string &interfaceType,
142                                       const std::map<std::string, std::string> &queryParams,
143                                       ResponseCallback callback)
144 {
145     if (!callback)
146     {
147         OC_LOG(ERROR, TAG, "Invalid callback!");
148         throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid callback!");
149     }
150
151     if (!m_getRequestSender)
152     {
153         OC_LOG(ERROR, TAG, "Invalid GET request sender!");
154         throw NoSupportException("Can not send GET request on this resource!");
155     }
156
157     m_getRequestSender->sendRequest(interfaceType, queryParams,
158                                     nullptr, std::bind(
159                                         &SimulatorRemoteResourceImpl::onResponseReceived,
160                                         this, std::placeholders::_1, std::placeholders::_2, callback));
161 }
162
163 void SimulatorRemoteResourceImpl::get(const std::map<std::string, std::string> &queryParams,
164                                       ResponseCallback callback)
165 {
166     if (!callback)
167     {
168         OC_LOG(ERROR, TAG, "Invalid callback!");
169         throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid callback!");
170     }
171
172     if (!m_getRequestSender)
173     {
174         OC_LOG(ERROR, TAG, "Invalid GET request sender !");
175         throw NoSupportException("Can not send GET request on this resource!");
176     }
177
178     m_getRequestSender->sendRequest(std::string(), queryParams,
179                                     nullptr, std::bind(
180                                         &SimulatorRemoteResourceImpl::onResponseReceived,
181                                         this, std::placeholders::_1, std::placeholders::_2, callback));
182 }
183
184 void SimulatorRemoteResourceImpl::put(const std::string &interfaceType,
185                                       const std::map<std::string, std::string> &queryParams,
186                                       SimulatorResourceModelSP representation,
187                                       ResponseCallback callback)
188 {
189     if (!callback)
190     {
191         OC_LOG(ERROR, TAG, "Invalid callback!");
192         throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid callback!");
193     }
194
195     if (!m_putRequestSender)
196     {
197         OC_LOG(ERROR, TAG, "Invalid PUT request sender !");
198         throw NoSupportException("Can not send PUT request on this resource!");
199     }
200
201     m_putRequestSender->sendRequest(interfaceType, queryParams,
202                                     representation, std::bind(
203                                         &SimulatorRemoteResourceImpl::onResponseReceived,
204                                         this, std::placeholders::_1, std::placeholders::_2, callback));
205 }
206
207 void SimulatorRemoteResourceImpl::put(const std::map<std::string, std::string> &queryParams,
208                                       SimulatorResourceModelSP representation,
209                                       ResponseCallback callback)
210 {
211     if (!callback)
212     {
213         OC_LOG(ERROR, TAG, "Invalid callback!");
214         throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid callback!");
215     }
216
217     if (!m_putRequestSender)
218     {
219         OC_LOG(ERROR, TAG, "Invalid PUT request sender !");
220         throw NoSupportException("Can not send PUT request on this resource!");
221     }
222
223     m_putRequestSender->sendRequest(std::string(), queryParams,
224                                     representation, std::bind(
225                                         &SimulatorRemoteResourceImpl::onResponseReceived,
226                                         this, std::placeholders::_1, std::placeholders::_2, callback));
227 }
228
229 void SimulatorRemoteResourceImpl::post(const std::string &interfaceType,
230                                        const std::map<std::string, std::string> &queryParams,
231                                        SimulatorResourceModelSP representation,
232                                        ResponseCallback callback)
233 {
234     if (!callback)
235     {
236         OC_LOG(ERROR, TAG, "Invalid callback!");
237         throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid callback!");
238     }
239
240     if (!m_postRequestSender)
241     {
242         OC_LOG(ERROR, TAG, "Invalid POST request sender !");
243         throw NoSupportException("Can not send POST request on this resource!");
244     }
245
246     m_postRequestSender->sendRequest(interfaceType, queryParams,
247                                      representation, std::bind(
248                                          &SimulatorRemoteResourceImpl::onResponseReceived,
249                                          this, std::placeholders::_1, std::placeholders::_2, callback));
250 }
251
252 void SimulatorRemoteResourceImpl::post(const std::map<std::string, std::string> &queryParams,
253                                        SimulatorResourceModelSP representation,
254                                        ResponseCallback callback)
255 {
256     if (!callback)
257     {
258         OC_LOG(ERROR, TAG, "Invalid callback!");
259         throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid callback!");
260     }
261
262     if (!m_postRequestSender)
263     {
264         OC_LOG(ERROR, TAG, "Invalid POST request sender !");
265         throw NoSupportException("Can not send POST request on this resource!");
266     }
267
268     m_postRequestSender->sendRequest(std::string(), queryParams,
269                                      representation, std::bind(
270                                          &SimulatorRemoteResourceImpl::onResponseReceived,
271                                          this, std::placeholders::_1, std::placeholders::_2, callback));
272 }
273
274 int SimulatorRemoteResourceImpl::startVerification(RequestType type,
275         StateCallback callback)
276 {
277     if (!callback)
278     {
279         OC_LOG(ERROR, TAG, "Invalid callback!");
280         throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid callback!");
281     }
282
283     if (!m_autoRequestGenMngr)
284     {
285         OC_LOG(ERROR, TAG, "Invalid auto request generation manager !");
286         throw NoSupportException("Resource is not configured with RAML!");
287     }
288
289     if (m_requestModelList.end() == m_requestModelList.find(type))
290         throw NoSupportException("Resource does not support this request type!");
291
292     // Local callback for handling progress sate callback
293     AutoRequestGeneration::ProgressStateCallback localCallback = [this, callback](
294                 int sessionId, OperationState state)
295     {
296         callback(m_id, sessionId, state);
297     };
298
299     switch (type)
300     {
301         case RequestType::RQ_TYPE_GET:
302             if (m_getRequestSender)
303             {
304                 return m_autoRequestGenMngr->startOnGET(m_getRequestSender,
305                                     m_requestModelList[RequestType::RQ_TYPE_GET]->getQueryParams(),
306                                     localCallback);
307             }
308             break;
309
310         case RequestType::RQ_TYPE_PUT:
311             if (m_putRequestSender)
312             {
313                 return m_autoRequestGenMngr->startOnPUT(m_putRequestSender,
314                                     m_requestModelList[RequestType::RQ_TYPE_PUT]->getQueryParams(),
315                                     m_requestModelList[RequestType::RQ_TYPE_PUT]->getRepSchema(),
316                                     localCallback);
317             }
318             break;
319
320         case RequestType::RQ_TYPE_POST:
321             if (m_postRequestSender)
322             {
323                 return m_autoRequestGenMngr->startOnPOST(m_putRequestSender,
324                                     m_requestModelList[RequestType::RQ_TYPE_POST]->getQueryParams(),
325                                     m_requestModelList[RequestType::RQ_TYPE_POST]->getRepSchema(),
326                                     localCallback);
327             }
328             break;
329
330         case RequestType::RQ_TYPE_DELETE:
331         default:
332             throw NoSupportException("Resource does not support this request type!");
333     }
334
335     return -1; // Code should not reach here
336 }
337
338 void SimulatorRemoteResourceImpl::stopVerification(int id)
339 {
340     if (id < 0)
341     {
342         OC_LOG(ERROR, TAG, "Invalid session id!");
343         throw InvalidArgsException(SIMULATOR_INVALID_PARAM, "Invalid ID!");
344     }
345
346     if (!m_autoRequestGenMngr)
347     {
348         OC_LOG(ERROR, TAG, "Invalid auto request generation manager !");
349         throw NoSupportException("Resource is not configured with RAML!");
350     }
351
352     m_autoRequestGenMngr->stop(id);
353 }
354
355 void SimulatorRemoteResourceImpl::configure(const std::string &path)
356 {
357     if (path.empty())
358     {
359         OC_LOG(ERROR, TAG, "Invalid path given for configuration!");
360         throw InvalidArgsException(SIMULATOR_INVALID_PARAM, "Empty path string!");
361     }
362
363     std::shared_ptr<RAML::RamlParser> ramlParser = std::make_shared<RAML::RamlParser>(path);
364     RAML::RamlPtr raml = ramlParser->getRamlPtr();
365
366     configure(raml);
367 }
368
369 void SimulatorRemoteResourceImpl::configure(std::shared_ptr<RAML::Raml> &raml)
370 {
371     m_requestModelList = RequestModelBuilder(raml).build(m_ocResource->uri());
372     if (m_getRequestSender &&
373         m_requestModelList.end() != m_requestModelList.find(RequestType::RQ_TYPE_GET))
374     {
375         m_getRequestSender->setRequestModel(m_requestModelList[RequestType::RQ_TYPE_GET]);
376     }
377
378     if (m_putRequestSender &&
379         m_requestModelList.end() != m_requestModelList.find(RequestType::RQ_TYPE_PUT))
380     {
381         m_putRequestSender->setRequestModel(m_requestModelList[RequestType::RQ_TYPE_PUT]);
382     }
383
384     if (m_postRequestSender &&
385         m_requestModelList.end() != m_requestModelList.find(RequestType::RQ_TYPE_POST))
386     {
387         m_postRequestSender->setRequestModel(m_requestModelList[RequestType::RQ_TYPE_POST]);
388     }
389
390     if (!m_autoRequestGenMngr)
391     {
392         m_autoRequestGenMngr = std::make_shared<AutoRequestGenMngr>();
393     }
394 }
395
396 void SimulatorRemoteResourceImpl::onResponseReceived(SimulatorResult result,
397         SimulatorResourceModelSP repModel,
398         ResponseCallback clientCallback)
399 {
400     clientCallback(m_id, result, repModel);
401 }
402
403 SimulatorConnectivityType SimulatorRemoteResourceImpl::convertConnectivityType(
404     OCConnectivityType type) const
405 {
406     switch (type)
407     {
408         case CT_ADAPTER_IP:
409             return SIMULATOR_CT_ADAPTER_IP;
410
411         case CT_IP_USE_V4:
412             return SIMULATOR_CT_IP_USE_V4 ;
413
414         case CT_IP_USE_V6:
415             return SIMULATOR_CT_IP_USE_V6;
416
417         case CT_ADAPTER_GATT_BTLE:
418             return SIMULATOR_CT_ADAPTER_GATT_BTLE;
419
420         case CT_ADAPTER_RFCOMM_BTEDR:
421             return SIMULATOR_CT_ADAPTER_RFCOMM_BTEDR;
422
423         default:
424             return SIMULATOR_CT_DEFAULT;
425     }
426 }