Imported Upstream version 0.9.1
[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 #include "SSMResourceServer.h"
21 #include "SSMCore.h"
22 #include "Common/PlatformLayer.h"
23 #include "Common/InternalInterface.h"
24 using namespace OC;
25
26 static std::vector< std::map<std::string, std::string> > g_vecQueryEventResults;
27
28 class CQueryEngineEvent: public IQueryEngineEvent
29 {
30     private:
31         std::string m_queryEngineId;
32         OCResourceHandle m_hSSMResource;
33
34     public:
35         /* Constructor */
36         CQueryEngineEvent(std::string queryEngineId, OCResourceHandle resourceHandle)
37         {
38             m_queryEngineId = queryEngineId;
39             m_hSSMResource = resourceHandle;
40         }
41
42         SSMRESULT onQueryEngineEvent(int cqid, IDataReader *pResult)
43         {
44             int dataCount = 0;
45             IModelData *pModelData = NULL;
46             std::vector < std::string > affectedModels;
47
48             std::map<std::string, std::string> queryEventResult;
49
50             std::stringstream sstream;
51
52             // QueryEngine Id
53             queryEventResult["queryEngineId"] = m_queryEngineId;
54
55             // CQID
56             sstream << cqid;
57             queryEventResult["CQID"] = sstream.str();
58             sstream.str("");
59
60             pResult->getAffectedModels(&affectedModels);
61
62             // Affected Model Count
63             sstream << affectedModels.size();
64             queryEventResult["modelCount"] = sstream.str();
65             sstream.str("");
66
67             //TODO: we assume that contains only one model at time
68             for (std::vector< std::string >::iterator itor = affectedModels.begin();
69                  itor != affectedModels.end(); ++itor)
70             {
71                 // Model Name
72                 sstream << (*itor);
73                 queryEventResult["modelName"] = sstream.str();
74                 sstream.str("");
75
76                 pResult->getModelDataCount(*itor, &dataCount);
77
78                 // Data Count
79                 sstream << dataCount;
80                 queryEventResult["dataCount"] = sstream.str();
81                 sstream.str("");
82
83                 //FixME: we have to support multiple data count
84                 for (int i = 0; i < dataCount; i++)
85                 {
86                     pResult->getModelData(*itor, i, &pModelData);
87
88                     // Data Id
89                     sstream << pModelData->getDataId();
90                     queryEventResult["dataId"] = sstream.str();
91                     sstream.str("");
92
93                     // Property Count
94                     sstream << pModelData->getPropertyCount();
95                     queryEventResult["propertyCount"] = sstream.str();
96                     sstream.str("");
97
98                     for (int j = 0; j < pModelData->getPropertyCount(); j++)
99                     {
100                         // Property Name & Value
101                         sstream << pModelData->getPropertyValue(j).c_str();
102                         queryEventResult[pModelData->getPropertyName(j).c_str()] = sstream.str();
103                         sstream.str("");
104                     }
105                 }
106             }
107
108             g_vecQueryEventResults.push_back(queryEventResult);
109
110             //TODO: need to modify for notifying proper clients
111             if (OCPlatform::notifyAllObservers(m_hSSMResource) != OC_STACK_OK)
112                 return SSM_E_FAIL;
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::RequestFlag)
199         {
200             // If the request type is GET
201             if (requestType == "GET")
202             {
203                 std::map<std::string, std::string> responseAttributeMap;
204
205                 OCRepresentation rep = request->getResourceRepresentation();
206
207                 if (g_vecQueryEventResults.size() > 0)
208                 {
209                     responseAttributeMap = g_vecQueryEventResults.front();
210                     g_vecQueryEventResults.erase(g_vecQueryEventResults.begin());
211                 }
212
213                 if (response)
214                 {
215                     for (std::map<std::string, std::string>::iterator itor =
216                              responseAttributeMap.begin(); itor != responseAttributeMap.end();
217                          ++itor)
218                     {
219                         rep.setValue(itor->first, itor->second);
220                     }
221
222                     response->setErrorCode(200);
223                     response->setResourceRepresentation(rep, DEFAULT_INTERFACE);
224                 }
225             }
226             else if (requestType == "PUT")
227             {
228                 OCRepresentation rep = request->getResourceRepresentation();
229
230                 IQueryEngine *pQueryEngine = NULL;
231
232                 std::stringstream sstream;
233
234                 // Process query params and do required operations ..
235                 if (rep.getValue<std::string>("command") == "CreateQueryEngine")
236                 {
237                     CQueryEngineEvent *queryEngineEvent = NULL;
238
239                     res = CreateQueryEngine(&pQueryEngine);
240
241                     if (res != SSM_S_OK)
242                     {
243                         rep.setValue("error", "CreateQueryEngine failed");
244                         goto CLEANUP;
245                     }
246
247                     sstream << reinterpret_cast<intptr_t>(pQueryEngine);
248
249                     // Register QueryEngineEvent
250                     queryEngineEvent = new CQueryEngineEvent(sstream.str(), m_hSSMResource);
251
252                     if (queryEngineEvent == NULL)
253                     {
254                         rep.setValue("error", "QueryEngineEvent create failed");
255                         goto CLEANUP;
256                     }
257
258                     res = pQueryEngine->registerQueryEvent(queryEngineEvent);
259
260                     if (res != SSM_S_OK)
261                     {
262                         rep.setValue("error", "RegisterQueryEvent failed");
263                         goto CLEANUP;
264                     }
265
266                     rep.setValue("queryEngineId", sstream.str());
267                 }
268                 else if (rep.getValue<std::string>("command") == "ReleaseQueryEngine")
269                 {
270                     pQueryEngine = (IQueryEngine *) std::stoll(
271                                        rep.getValue<std::string>("queryEngineId"));
272
273                     ReleaseQueryEngine(pQueryEngine);
274                 }
275                 else if (rep.getValue<std::string>("command") == "ExecuteContextQuery")
276                 {
277                     int CQID = 0;
278
279                     pQueryEngine = (IQueryEngine *)std::stoll(
280                                        rep.getValue<std::string>("queryEngineId"));
281
282                     res = pQueryEngine->executeContextQuery(
283                               rep.getValue<std::string>("contextQuery"), &CQID);
284
285                     if (res != SSM_S_OK)
286                     {
287                         rep.setValue("error", "ExecuteContextQuery failed");
288                         goto CLEANUP;
289                     }
290
291                     sstream << CQID;
292
293                     rep.setValue("CQID", sstream.str());
294                 }
295                 else if (rep.getValue<std::string>("command") == "KillContextQuery")
296                 {
297                     pQueryEngine = (IQueryEngine *)std::stoll(
298                                        rep.getValue<std::string>("queryEngineId"));
299
300                     res = pQueryEngine->killContextQuery(std::stoi(rep.getValue<std::string>("CQID")));
301
302                     if (res != SSM_S_OK)
303                     {
304                         rep.setValue("error", "KillContextQuery failed");
305                         goto CLEANUP;
306                     }
307                 }
308
309 CLEANUP:
310                 if (response)
311                 {
312                     response->setErrorCode(200);
313                     response->setResourceRepresentation(rep, DEFAULT_INTERFACE);
314                 }
315             }
316             else if (requestType == "POST")
317             {
318                 // POST request operations
319             }
320             else if (requestType == "DELETE")
321             {
322                 // DELETE request operations
323             }
324         }
325
326         if (requestFlag & RequestHandlerFlag::ObserverFlag)
327         {
328             // perform observe related operations on the resource.
329         }
330     }
331
332     return OCPlatform::sendResponse(response) == OC_STACK_OK ? OC_EH_OK : OC_EH_ERROR;
333 }