iotivity 0.9.0
[platform/upstream/iotivity.git] / service / soft-sensor-manager / SSMCore / src / SSMInterface / SSMResourceServer.cpp
1 /******************************************************************
2  *
3  * Copyright 2014 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 "SSMResourceServer.h"
22 #include "SSMCore.h"
23 #include "Common/PlatformLayer.h"
24 #include "Common/InternalInterface.h"
25 using namespace OC;
26
27 static std::vector< std::map<std::string, std::string> > g_vecQueryEventResults;
28
29 class CQueryEngineEvent: public IQueryEngineEvent
30 {
31     private:
32         std::string m_queryEngineId;
33         OCResourceHandle m_hSSMResource;
34
35     public:
36         /* Constructor */
37         CQueryEngineEvent(std::string queryEngineId, OCResourceHandle resourceHandle)
38         {
39             m_queryEngineId = queryEngineId;
40             m_hSSMResource = resourceHandle;
41         }
42
43         SSMRESULT onQueryEngineEvent(IN int cqid, IN IDataReader *pResult)
44         {
45             int dataCount = 0;
46             IModelData *pModelData = NULL;
47             std::vector < std::string > affectedModels;
48
49             std::map<std::string, std::string> queryEventResult;
50
51             std::stringstream sstream;
52
53             // QueryEngine Id
54             queryEventResult["queryEngineId"] = m_queryEngineId;
55
56             // CQID
57             sstream << cqid;
58             queryEventResult["CQID"] = sstream.str();
59             sstream.str("");
60
61             pResult->getAffectedModels(&affectedModels);
62
63             // Affected Model Count
64             sstream << affectedModels.size();
65             queryEventResult["modelCount"] = sstream.str();
66             sstream.str("");
67
68             //TODO: we assume that contains only one model at time
69             for (std::vector< std::string >::iterator itor = affectedModels.begin();
70                  itor != affectedModels.end(); ++itor)
71             {
72                 // Model Name
73                 sstream << (*itor);
74                 queryEventResult["modelName"] = sstream.str();
75                 sstream.str("");
76
77                 pResult->getModelDataCount(*itor, &dataCount);
78
79                 // Data Count
80                 sstream << dataCount;
81                 queryEventResult["dataCount"] = sstream.str();
82                 sstream.str("");
83
84                 //FixME: we have to support multiple data count
85                 for (int i = 0; i < dataCount; i++)
86                 {
87                     pResult->getModelData(*itor, i, &pModelData);
88
89                     // Data Id
90                     sstream << pModelData->getDataId();
91                     queryEventResult["dataId"] = sstream.str();
92                     sstream.str("");
93
94                     // Property Count
95                     sstream << pModelData->getPropertyCount();
96                     queryEventResult["propertyCount"] = sstream.str();
97                     sstream.str("");
98
99                     for (int j = 0; j < pModelData->getPropertyCount(); j++)
100                     {
101                         // Property Name & Value
102                         sstream << pModelData->getPropertyValue(j).c_str();
103                         queryEventResult[pModelData->getPropertyName(j).c_str()] = sstream.str();
104                         sstream.str("");
105                     }
106                 }
107             }
108
109             g_vecQueryEventResults.push_back(queryEventResult);
110
111             //TODO: need to modify for notifying proper clients
112             OCPlatform::notifyAllObservers(m_hSSMResource);
113
114             return SSM_S_OK;
115         }
116 };
117
118 SSMResourceServer::SSMResourceServer()
119 {
120     m_hSSMResource = NULL;
121 }
122
123 SSMResourceServer::~SSMResourceServer()
124 {
125 }
126
127 int SSMResourceServer::initializeManager(std::string &xmlDescription)
128 {
129     SSMRESULT res = SSM_E_FAIL;
130
131     SSM_CLEANUP_ASSERT(InitializeSSMCore(xmlDescription));
132     SSM_CLEANUP_ASSERT(StartSSMCore());
133
134     if (createResource() != 0)
135     {
136         SSM_CLEANUP_ASSERT (SSM_E_FAIL);
137     }
138
139 CLEANUP:
140     if (res != SSM_S_OK)
141         return -1;
142
143     return 0;
144 }
145
146 int SSMResourceServer::terminateManager()
147 {
148     SSMRESULT res = SSM_E_FAIL;
149
150     SSM_CLEANUP_ASSERT(StopSSMCore());
151     SSM_CLEANUP_ASSERT(TerminateSSMCore());
152
153 CLEANUP:
154     if (res != SSM_S_OK)
155         return -1;
156
157     return 0;
158 }
159
160 int SSMResourceServer::createResource()
161 {
162     std::string resourceURI = "/service/SoftSensorManager"; // URI of the resource
163     std::string resourceTypeName = "core.SoftSensorManager"; // resource type name.
164     std::string resourceInterface = DEFAULT_INTERFACE; // resource interface.
165
166     // OCResourceProperty is defined ocstack.h
167     uint8_t resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE;
168
169     // This will internally create and register the resource.
170     OCStackResult result = OCPlatform::registerResource(m_hSSMResource, resourceURI,
171                            resourceTypeName, resourceInterface,
172                            std::bind(&SSMResourceServer::entityHandler, this, std::placeholders::_1
173                                     ), resourceProperty);
174
175     if (OC_STACK_OK != result)
176     {
177         return -1;
178     }
179
180     return 0;
181 }
182
183 OCEntityHandlerResult SSMResourceServer::entityHandler(std::shared_ptr< OCResourceRequest > request)
184 {
185     SSMRESULT res = SSM_E_FAIL;
186
187     auto response = std::make_shared<OC::OCResourceResponse>();
188
189     if (request)
190     {
191         // Get the request type and request flag
192         std::string requestType = request->getRequestType();
193         int requestFlag = request->getRequestHandlerFlag();
194
195         response->setRequestHandle(request->getRequestHandle());
196         response->setResourceHandle(request->getResourceHandle());
197
198         if (requestFlag & RequestHandlerFlag::InitFlag)
199         {
200             // entity handler to perform resource initialization operations
201         }
202
203         if (requestFlag & RequestHandlerFlag::RequestFlag)
204         {
205             cout << "\t\trequestFlag : Request\n";
206
207             // If the request type is GET
208             if (requestType == "GET")
209             {
210                 std::map<std::string, std::string> responseAttributeMap;
211
212                 OCRepresentation rep = request->getResourceRepresentation();
213
214                 if (g_vecQueryEventResults.size() > 0)
215                 {
216                     responseAttributeMap = g_vecQueryEventResults.front();
217                     g_vecQueryEventResults.erase(g_vecQueryEventResults.begin());
218                 }
219
220                 if (response)
221                 {
222                     for (std::map<std::string, std::string>::iterator itor =
223                              responseAttributeMap.begin(); itor != responseAttributeMap.end();
224                          ++itor)
225                     {
226                         rep.setValue(itor->first, itor->second);
227                     }
228
229                     response->setErrorCode(200);
230                     response->setResourceRepresentation(rep, DEFAULT_INTERFACE);
231                 }
232             }
233             else if (requestType == "PUT")
234             {
235                 OCRepresentation rep = request->getResourceRepresentation();
236
237                 IQueryEngine *pQueryEngine = NULL;
238
239                 std::stringstream sstream;
240
241                 // Process query params and do required operations ..
242                 if (rep.getValue<std::string>("command") == "CreateQueryEngine")
243                 {
244                     CQueryEngineEvent *queryEngineEvent = NULL;
245
246                     res = CreateQueryEngine(&pQueryEngine);
247
248                     if (res != SSM_S_OK)
249                     {
250                         rep.setValue("error", "CreateQueryEngine failed");
251                         goto CLEANUP;
252                     }
253
254                     sstream << reinterpret_cast<intptr_t>(pQueryEngine);
255
256                     // Register QueryEngineEvent
257                     queryEngineEvent = new CQueryEngineEvent(sstream.str(), m_hSSMResource);
258
259                     if (queryEngineEvent == NULL)
260                     {
261                         rep.setValue("error", "QueryEngineEvent create failed");
262                         goto CLEANUP;
263                     }
264
265                     res = pQueryEngine->registerQueryEvent(queryEngineEvent);
266
267                     if (res != SSM_S_OK)
268                     {
269                         rep.setValue("error", "RegisterQueryEvent failed");
270                         goto CLEANUP;
271                     }
272
273                     rep.setValue("queryEngineId", sstream.str());
274                 }
275                 else if (rep.getValue<std::string>("command") == "ReleaseQueryEngine")
276                 {
277                     pQueryEngine = (IQueryEngine *) std::stoi(
278                                        rep.getValue<std::string>("queryEngineId"));
279
280                     ReleaseQueryEngine(pQueryEngine);
281                 }
282                 else if (rep.getValue<std::string>("command") == "ExecuteContextQuery")
283                 {
284                     int CQID = 0;
285
286                     pQueryEngine = (IQueryEngine *) std::stoi(
287                                        rep.getValue<std::string>("queryEngineId"));
288
289                     res = pQueryEngine->executeContextQuery(
290                               rep.getValue<std::string>("contextQuery"), &CQID);
291
292                     if (res != SSM_S_OK)
293                     {
294                         rep.setValue("error", "ExecuteContextQuery failed");
295                         goto CLEANUP;
296                     }
297
298                     sstream << CQID;
299
300                     rep.setValue("CQID", sstream.str());
301                 }
302                 else if (rep.getValue<std::string>("command") == "KillContextQuery")
303                 {
304                     pQueryEngine = (IQueryEngine *) std::stoi(
305                                        rep.getValue<std::string>("queryEngineId"));
306
307                     res = pQueryEngine->killContextQuery(std::stoi(rep.getValue<std::string>("CQID")));
308
309                     if (res != SSM_S_OK)
310                     {
311                         rep.setValue("error", "KillContextQuery failed");
312                         goto CLEANUP;
313                     }
314                 }
315
316 CLEANUP:
317                 if (response)
318                 {
319                     response->setErrorCode(200);
320                     response->setResourceRepresentation(rep, DEFAULT_INTERFACE);
321                 }
322             }
323             else if (requestType == "POST")
324             {
325                 // POST request operations
326             }
327             else if (requestType == "DELETE")
328             {
329                 // DELETE request operations
330             }
331         }
332
333         if (requestFlag & RequestHandlerFlag::ObserverFlag)
334         {
335             // perform observe related operations on the resource.
336         }
337     }
338
339     return OCPlatform::sendResponse(response) == OC_STACK_OK ? OC_EH_OK : OC_EH_ERROR;
340 }