Imported Upstream version 0.9.1
[platform/upstream/iotivity.git] / service / soft-sensor-manager / SSMCore / src / QueryProcessor / PropagationEngine.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 "PropagationEngine.h"
21 #include "ContextModel.h"
22
23 SSMRESULT CPropagationEngine::finalConstruct()
24 {
25     SSMRESULT               res = SSM_E_FAIL;
26
27     SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_ITasker, (IBase **)&m_pTasker));
28
29     SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_IContextDataReader, (IBase **)&m_pContextDataReader));
30
31     SSM_CLEANUP_ASSERT(m_pContextDataReader->registerContextModelAccessor(this));
32
33     SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_IEvaluationEngine, (IBase **)&m_pEvaluationEngine));
34
35     SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_IContextRepository, (IBase **)&m_pContextRepository));
36
37     SSM_CLEANUP_ASSERT(m_pContextRepository->registerResourceFinderEvent(this));
38
39     SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_ISensingEngine, (IBase **)&m_pSensingEngine));
40
41     SSM_CLEANUP_ASSERT(initializeEngine());
42
43 CLEANUP:
44     return res;
45 }
46
47 void CPropagationEngine::finalRelease()
48 {
49     terminateEngine();
50
51     for (std::map<std::string, IContextModel *>::iterator itor = m_installedContextModel.begin();
52          itor != m_installedContextModel.end(); ++itor)
53     {
54         ((CContextModel *)itor->second)->registerContextModelEvent(NULL);
55         SAFE_RELEASE(itor->second);
56     }
57
58     for (VirtualModelMap::iterator itor = m_lookUpContextModel.begin();
59          itor != m_lookUpContextModel.end(); ++itor)
60     {
61         for (std::vector< std::pair<ModelConditionVec, IConditionedQuery *> >::iterator inneritor =
62                  itor->second.begin(); inneritor != itor->second.end(); ++inneritor)
63         {
64             SAFE_RELEASE(inneritor->second);
65         }
66     }
67 }
68
69 SSMRESULT CPropagationEngine::findContextModel(std::string modelName,
70         IContextModel  **ppContextModel)
71 {
72     SSMRESULT res = SSM_S_FALSE;
73     std::map<std::string, IContextModel *>::iterator idxContextModel;
74
75     m_mtxContextModelList.lock();
76     idxContextModel = m_installedContextModel.find(modelName);
77
78     if (idxContextModel != m_installedContextModel.end())
79     {
80         SSM_CLEANUP_ASSERT(idxContextModel->second->queryInterface(OID_IContextModel,
81                            (IBase **)ppContextModel));
82     }
83
84 CLEANUP:
85     m_mtxContextModelList.unlock();
86     return res;
87 }
88
89 SSMRESULT CPropagationEngine::registerCondition(IContextModel *pContextModel,
90         ModelConditionVec *pConditions, IConditionedQuery *pConditionedQuery)
91 {
92     SSMRESULT res = SSM_E_FAIL;
93     IConditionedModel           *pConditionedModel = NULL;
94
95     SSM_CLEANUP_ASSERT(pContextModel->createConditionedModel(pConditions, &pConditionedModel));
96     SSM_CLEANUP_ASSERT(pConditionedQuery->registerConditionedModel(pConditionedModel));
97
98     res = SSM_S_OK;
99
100 CLEANUP:
101     SAFE_RELEASE(pConditionedModel);
102     return res;
103 }
104
105 SSMRESULT CPropagationEngine::registerVirtualCondition(std::string virtualContextModelName,
106         ModelConditionVec *pConditions, IConditionedQuery *pConditionedQuery)
107 {
108     pConditionedQuery->addRef();
109     m_mtxLookUpList.lock();
110     m_lookUpContextModel[virtualContextModelName].push_back(std::make_pair(*pConditions,
111             pConditionedQuery));
112     m_mtxLookUpList.unlock();
113     return SSM_S_OK;
114 }
115
116 SSMRESULT CPropagationEngine::propagateNewModel(std::string newModelName,
117         IContextModel *pContextModel)
118 {
119     SSMRESULT res = SSM_E_FAIL;
120     VirtualModelMap::iterator   itorVModels;
121
122     m_mtxLookUpList.lock();
123     itorVModels = m_lookUpContextModel.find(newModelName);
124
125     if (itorVModels != m_lookUpContextModel.end())
126     {
127         for (std::vector< std::pair<ModelConditionVec, IConditionedQuery *> >::iterator itor =
128                  itorVModels->second.begin(); itor != itorVModels->second.end(); ++itor)
129         {
130             SSM_CLEANUP_ASSERT(registerCondition(pContextModel, &itor->first, itor->second));
131
132             SAFE_RELEASE(itor->second);
133         }
134
135         m_lookUpContextModel.erase(itorVModels);
136     }
137
138     res = SSM_S_OK;
139
140 CLEANUP:
141     m_mtxLookUpList.unlock();
142     return res;
143 }
144
145 SSMRESULT CPropagationEngine::addResourceFromGetList()
146 {
147     SSMRESULT res = SSM_E_FAIL;
148     std::vector<ISSMResource *>      contextModelList;
149     std::stringstream               sstream;
150
151     m_pSensingEngine->getList(&contextModelList);
152     for (std::vector<ISSMResource *>::iterator itor = contextModelList.begin();
153          itor != contextModelList.end(); ++itor)
154     {
155         SSM_CLEANUP_ASSERT(installContextModelFromISSMResource(*itor));
156     }
157
158     res = SSM_S_OK;
159
160 CLEANUP:
161     return res;
162 }
163
164 //Install new resource and update Device table
165 SSMRESULT CPropagationEngine::installContextModelFromISSMResource(ISSMResource *pSSMResource)
166 {
167     SSMRESULT res = SSM_E_FAIL;
168
169     ModelProperty               modelProperty;
170     ModelPropertyVec            modelProperties;
171     CObject<CContextModel>      *pContextModel;
172     int                         deviceId = 0;
173     std::string                 lifeTime;
174
175     switch ((res = findContextModel(pSSMResource->type.c_str(), (IContextModel **)&pContextModel)))
176     {
177         //we found model
178         case SSM_S_OK:
179             break;
180
181         //no models using that name, create new one
182         case SSM_S_FALSE:
183             for (std::vector<std::map<std::string, std::string> >::iterator itor =
184                      pSSMResource->outputProperty.begin(); itor != pSSMResource->outputProperty.end();
185                  ++itor)
186             {
187                 if ((*itor)["name"] == "lifetime")
188                 {
189                     lifeTime = (*itor)["value"];
190                     continue;
191                 }
192
193                 modelProperty.propertyName = (*itor)["name"];
194                 if ((*itor)["type"] == "string")
195                 {
196                     modelProperty.propertyType = ModelProperty::TYPE_TEXT;
197                 }
198                 else if ((*itor)["type"] == "int")
199                 {
200                     modelProperty.propertyType = ModelProperty::TYPE_INTEGER;
201                 }
202                 else if ((*itor)["type"] == "double")
203                 {
204                     modelProperty.propertyType = ModelProperty::TYPE_REAL;
205                 }
206                 else if ((*itor)["type"] == "float")
207                 {
208                     modelProperty.propertyType = ModelProperty::TYPE_REAL;
209                 }
210                 else
211                 {
212                     modelProperty.propertyType = ModelProperty::TYPE_TEXT;
213                 }
214                 modelProperties.push_back(modelProperty);
215             }
216
217             //Install new resource
218             SSM_CLEANUP_ASSERT(installContextModel(m_pDeviceModel, IContextModel::CONSTRUCTION_TYPE_EXTERNAL,
219                                                    pSSMResource->type.c_str(), &modelProperties, (IContextModel **)&pContextModel));
220
221             if (lifeTime.length() > 0)
222             {
223                 pContextModel->setLifeTime(lifeTime);
224             }
225
226             modelProperties.clear();
227             break;
228
229         default:
230             goto CLEANUP;
231     }
232
233     //Update Device data to DB
234     SSM_CLEANUP_ASSERT(updateDeviceInfo(pSSMResource, &deviceId));
235
236     //TODO: Must be modified for restructuring
237     pContextModel->addSSMResourceAndDeviceDataId(pSSMResource->type, deviceId, pSSMResource);
238
239     res = SSM_S_OK;
240
241 CLEANUP:
242     SAFE_RELEASE(pContextModel);
243     return res;
244 }
245
246 SSMRESULT CPropagationEngine::updateDeviceInfo(ISSMResource *pSSMResource, int *deviceId)
247 {
248     SSMRESULT res = SSM_E_FAIL;
249
250     ModelProperty               modelProperty;
251     ModelPropertyVec            modelProperties;
252     std::map<std::string, int>::iterator    itorSearchedDeviceId;
253     int                         deviceDataId;
254
255     modelProperty.propertyName = "fname";
256     modelProperty.propertyType = ModelProperty::TYPE_TEXT;
257     modelProperty.propertyValue = pSSMResource->friendlyName;
258     modelProperties.push_back(modelProperty);
259
260     modelProperty.propertyName = "ip";
261     modelProperty.propertyType = ModelProperty::TYPE_TEXT;
262     modelProperty.propertyValue = pSSMResource->ip;
263     modelProperties.push_back(modelProperty);
264
265     modelProperty.propertyName = "version";
266     modelProperty.propertyType = ModelProperty::TYPE_TEXT;
267     modelProperty.propertyValue = "1.0";
268     modelProperties.push_back(modelProperty);
269
270     itorSearchedDeviceId = m_searchedSensorDataId.find(pSSMResource->ip);
271
272     if (itorSearchedDeviceId == m_searchedSensorDataId.end())
273     {
274         SSM_CLEANUP_ASSERT(m_pDeviceModel->addModelData(1, &modelProperties, &deviceDataId));
275         m_searchedSensorDataId[pSSMResource->ip] = deviceDataId;
276     }
277     else
278     {
279         deviceDataId = m_searchedSensorDataId[pSSMResource->ip];
280     }
281
282     if (deviceId != NULL)
283         *deviceId = deviceDataId;
284
285     res = SSM_S_OK;
286
287 CLEANUP:
288     return res;
289 }
290
291 SSMRESULT CPropagationEngine::installCurrentSensors()
292 {
293     SSMRESULT res = SSM_E_FAIL;
294     std::vector<ISSMResource *>      contextModelList;
295
296     m_pSensingEngine->getList(&contextModelList);
297
298     for (std::vector<ISSMResource *>::iterator itor = contextModelList.begin();
299          itor != contextModelList.end(); ++itor)
300     {
301         SSM_CLEANUP_ASSERT(installContextModelFromISSMResource(*itor));
302     }
303
304     res = SSM_S_OK;
305
306 CLEANUP:
307     return res;
308 }
309
310 SSMRESULT CPropagationEngine::installContextModel(IContextModel *pParentModel,
311         IContextModel::ConstructionType constructionType, const char *modelName,
312         ModelPropertyVec *pModelDescs, IContextModel **ppContextModel)
313 {
314     SSMRESULT                   res = SSM_E_FAIL;
315     CObject<CContextModel>      *pNewModel;
316
317     SSM_CLEANUP_ASSERT(CreateInstance(OID_IContextModel, (IBase **)&pNewModel));
318     SSM_CLEANUP_ASSERT(pNewModel->create(constructionType, pParentModel, modelName, pModelDescs));
319     SSM_CLEANUP_ASSERT(pNewModel->registerContextModelEvent(this));
320
321     pNewModel->addRef();
322     m_mtxContextModelList.lock();
323     m_installedContextModel[modelName] = pNewModel;
324     m_mtxContextModelList.unlock();
325
326     SSM_CLEANUP_ASSERT(propagateNewModel(modelName, pNewModel));
327
328     if (ppContextModel)
329     {
330         SSM_CLEANUP_ASSERT(pNewModel->queryInterface(OID_IContextModel, (IBase **)ppContextModel));
331     }
332
333 CLEANUP:
334     SAFE_RELEASE(pNewModel);
335     return res;
336 }
337
338 SSMRESULT CPropagationEngine::cleanUpRemoteDeviceInfo()
339 {
340     SSMRESULT               res = SSM_E_FAIL;
341     ModelConditionVec       deviceCondition(1);
342     IConditionedModel       *pRemoteDeviceInformation = NULL;
343     IntVec                  deviceDataIds;
344
345     deviceCondition[0].modelProperty.propertyName = "dataId";
346     deviceCondition[0].modelProperty.propertyValue = "1";
347     deviceCondition[0].modelProperty.propertyType = ModelProperty::TYPE_NUMERIC;
348     deviceCondition[0].predicate = ModelCondition::PREDICATE_GT;
349     SSM_CLEANUP_ASSERT(m_pDeviceModel->createConditionedModel(&deviceCondition,
350                        &pRemoteDeviceInformation));
351     SSM_CLEANUP_ASSERT(pRemoteDeviceInformation->getAffectedData(&deviceDataIds));
352
353     for (unsigned int i = 0; i < deviceDataIds.size(); i++)
354     {
355         SSM_CLEANUP_ASSERT(m_pDeviceModel->deleteModelData(deviceDataIds[i]));
356     }
357
358 CLEANUP:
359     SAFE_RELEASE(pRemoteDeviceInformation);
360     return res;
361 }
362
363 void CPropagationEngine::onExecute(void *pArg)
364 {
365     SSMRESULT res = SSM_E_FAIL;
366
367     intptr_t         *pMessage = (intptr_t *)pArg;
368
369     RESOURCE_EVENT_TYPE eventType = (RESOURCE_EVENT_TYPE)pMessage[0];
370     ISSMResource            *pResource = (ISSMResource *)pMessage[1];
371
372     switch (eventType)
373     {
374         case SSM_EVENT_NORMAL:
375             SSM_CLEANUP_ASSERT(addResourceFromGetList());
376             break;
377
378         case SSM_EVENT_ADDED:
379             SSM_CLEANUP_ASSERT(installContextModelFromISSMResource(pResource));
380             break;
381
382         case SSM_REMOVED:
383             break;
384
385         case SSM_UPDATED:
386             break;
387
388         default:
389             break;
390     }
391
392 CLEANUP:
393     ;
394 }
395
396 void CPropagationEngine::onTerminate(void *pArg)
397 {
398     intptr_t         *pMessage = (intptr_t *)pArg;
399
400     delete[] pMessage;
401 }
402
403 int CPropagationEngine::onResourceEvent(RESOURCE_EVENT_TYPE eventType,
404                                         ISSMResource *pSSMResource, std::string info)
405 {
406     intptr_t          *pMessage = new intptr_t [2];
407
408     pMessage[0] = eventType;
409     pMessage[1] = reinterpret_cast<intptr_t>(pSSMResource);
410     return (int)m_pTasker->addTask(this, (void *)pMessage);
411 }
412
413 SSMRESULT CPropagationEngine::initializeEngine()
414 {
415     SSMRESULT               res = SSM_E_FAIL;
416     CObject<CContextModel>  *pRootModel = NULL;
417     ModelPropertyVec        rootModelProperties(1);
418
419     ModelPropertyVec        deviceModelProperties(3);
420
421     ISSMResource            ssmResource;
422
423     SSM_CLEANUP_ASSERT(m_pEvaluationEngine->initializeEngine());
424
425     //Create root model (Root)
426     rootModelProperties[0].propertyName = "name";
427     rootModelProperties[0].propertyType = ModelProperty::TYPE_TEXT;
428
429     SSM_CLEANUP_ASSERT(CreateInstance(OID_IContextModel, (IBase **)&pRootModel));
430
431     SSM_CLEANUP_ASSERT(pRootModel->create(IContextModel::CONSTRUCTION_TYPE_INTERNAL, NULL,
432                                           "root", &rootModelProperties));
433     SSM_CLEANUP_ASSERT(pRootModel->queryInterface(OID_IContextModel, (IBase **)&m_pRootModel));
434
435     //Create basic model (Device)
436     deviceModelProperties[0].propertyName = "fname";
437     deviceModelProperties[0].propertyType = ModelProperty::TYPE_TEXT;
438     deviceModelProperties[1].propertyName = "ip";
439     deviceModelProperties[1].propertyType = ModelProperty::TYPE_TEXT;
440     deviceModelProperties[2].propertyName = "version";
441     deviceModelProperties[2].propertyType = ModelProperty::TYPE_TEXT;
442
443     SSM_CLEANUP_ASSERT(installContextModel(m_pRootModel, IContextModel::CONSTRUCTION_TYPE_INTERNAL,
444                                            "Device",
445                                            &deviceModelProperties, &m_pDeviceModel));
446
447     ssmResource.ip = "coap://127.0.0.1/";
448     ssmResource.friendlyName = "MyDevice";
449
450     SSM_CLEANUP_ASSERT(updateDeviceInfo(&ssmResource, NULL));
451
452     SSM_CLEANUP_ASSERT(installCurrentSensors());
453
454 CLEANUP:
455     SAFE_RELEASE(pRootModel);
456     return res;
457 }
458
459 void CPropagationEngine::terminateEngine()
460 {
461     SSMRESULT               res = SSM_E_FAIL;
462
463     SSM_CLEANUP_ASSERT(cleanUpRemoteDeviceInfo());
464
465 CLEANUP:
466     return;
467 }
468
469 SSMRESULT CPropagationEngine::getContextModel(std:: string modelName,
470         IContextModel **ppContextModel)
471 {
472     SSMRESULT res = SSM_E_FAIL;
473
474     res = findContextModel(modelName, ppContextModel);
475
476     return res == SSM_S_OK ? SSM_S_OK : SSM_E_FAIL;
477 }
478
479 SSMRESULT CPropagationEngine::createConditionedQuery(IContextModel::ActivationType
480         activationType, QueryCondition *pQueryCondition, IConditionedQueryEvent *pEvent,
481         IConditionedQuery **ppConditionedQuery)
482 {
483     SSMRESULT res = SSM_E_FAIL;
484     CObject<CConditionedQuery>  *pConditionedQuery;
485     IContextModel               *pContextModel = NULL;
486
487     SSM_CLEANUP_ASSERT(CreateInstance(OID_IConditionedQuery, (IBase **)&pConditionedQuery));
488
489     SSM_CLEANUP_ASSERT(pConditionedQuery->create(activationType, pQueryCondition->size()));
490     for (QueryCondition::iterator itor = pQueryCondition->begin();
491          itor != pQueryCondition->end(); ++itor)
492     {
493         switch (findContextModel(itor->first, &pContextModel))
494         {
495             case SSM_S_OK:
496                 SSM_CLEANUP_ASSERT(registerCondition(pContextModel, &itor->second, pConditionedQuery));
497                 break;
498
499             case SSM_S_FALSE:
500                 SSM_CLEANUP_ASSERT(registerVirtualCondition(itor->first, &itor->second, pConditionedQuery));
501                 break;
502
503             default:
504                 res = SSM_E_FAIL;
505                 goto CLEANUP;
506         }
507         SAFE_RELEASE(pContextModel);
508     }
509
510     SSM_CLEANUP_ASSERT(pConditionedQuery->registerQueryConditionEvent(pEvent));
511
512     SSM_CLEANUP_ASSERT(pConditionedQuery->queryInterface(OID_IConditionedQuery,
513                        (IBase **)ppConditionedQuery));
514
515 CLEANUP:
516     SAFE_RELEASE(pConditionedQuery);
517     SAFE_RELEASE(pContextModel);
518     return res;
519 }
520
521 SSMRESULT CPropagationEngine::onModelStatusChange(IContextModel::Status newStatus,
522         ISSMResource *pSSMResource, IContextModel *pModel)
523 {
524     switch (newStatus)
525     {
526         case IContextModel::STATUS_ACTIVATE:
527             pModel->addRef();
528             m_pSensingEngine->registerContext(SSM_REPEAT, pSSMResource, (CContextModel *)pModel);
529             break;
530
531         case IContextModel::STATUS_DEACTIVATE:
532             m_pSensingEngine->unregisterContext(SSM_REPEAT, pSSMResource, (CContextModel *)pModel);
533             //pModel->CleanUpModelData();
534             pModel->release();
535             break;
536
537         case IContextModel::STATUS_START_READ_VALUE:
538             //Model must be released from OnEvent callType
539             pModel->addRef();
540             m_pSensingEngine->registerContext(SSM_ONCE, pSSMResource, (CContextModel *)pModel);
541             break;
542
543         case IContextModel::STATUS_STOP_READ_VALUE:
544             pModel->release();
545             break;
546
547         default:
548             break;
549     }
550
551     return SSM_S_OK;
552 }
553
554 SSMRESULT CPropagationEngine::onQueryContextModel(std::string modelName,
555         IContextModel **ppContextModel)
556 {
557     std::map<std::string, IContextModel *>::iterator     itorContextModel;
558
559     itorContextModel = m_installedContextModel.find(modelName);
560
561     if (itorContextModel == m_installedContextModel.end())
562     {
563         return SSM_E_FAIL;
564     }
565
566     return itorContextModel->second->queryInterface(OID_IContextModel, (IBase **)ppContextModel);
567 }