Implementation of APIs for managing resource list and callback
[platform/upstream/iotivity.git] / service / simulator / examples / server / service_provider.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_manager.h"
22
23 class AppLogger : public ILogger
24 {
25     public:
26         void write(std::string time, ILogger::Level level, std::string message)
27         {
28             std::cout << "[APPLogger] " << time << " " << ILogger::getString(level) << " " << message;
29         }
30 };
31 std::shared_ptr<AppLogger> gAppLogger(new AppLogger());
32
33 class SimLightResource
34 {
35     public:
36         void startTest()
37         {
38             printMenu();
39             bool cont = true;
40             while (cont)
41             {
42                 int choice = -1;
43                 std::cout << "Enter your choice: ";
44                 std::cin >> choice;
45                 if (choice < 0 || choice > 9)
46                 {
47                     std::cout << "Invaild choice !" << std::endl; continue;
48                 }
49
50                 switch (choice)
51                 {
52                     case 1: simulateResource(); break;
53                     case 2: displayResource(); break;
54                     case 3: deleteResource(); break;
55                     case 4: updateAttributePower(); break;
56                     case 5: updateAttributeIntensity(); break;
57                     case 6: automateResourceUpdate(); break;
58                     case 7: automateAttributeUpdate(); break;
59                     case 8: stopAutomation(); break;
60                     case 9: printMenu(); break;
61                     case 0: cont = false;
62                 }
63             }
64         }
65
66     private:
67         void printMenu()
68         {
69             std::cout << "########### LIGHT RESOURCE TESTING ###########" << std::endl;
70             std::cout << "1. Simulate resource" << std::endl;
71             std::cout << "2. Display resource information" << std::endl;
72             std::cout << "3. Delete resource" << std::endl;
73             std::cout << "4. Update attribute \"power\"" << std::endl;
74             std::cout << "5. Update attribute \"intensity\"" << std::endl;
75             std::cout << "6. Automate resource update" << std::endl;
76             std::cout << "7. Automate attributes update" << std::endl;
77             std::cout << "8. Stop Automation" << std::endl;
78             std::cout << "9: Help" << std::endl;
79             std::cout << "0. Exit" << std::endl;
80             std::cout << "#######################################" << std::endl;
81         }
82
83         int selectResource()
84         {
85             if (0 == m_resources.size())
86             {
87                 std::cout << "No resouces!" << std::endl;
88                 return -1;
89             }
90
91             int index = 1;
92             for (auto & resource : m_resources)
93             {
94                 std::cout << index++ << ": " << resource->getURI().c_str() << std::endl;
95             }
96
97             int choice = -1;
98             std::cout << "Choose the resource: ";
99             std::cin >> choice;
100
101             if (choice < 1 || choice > index - 1)
102             {
103                 std::cout << "Invalid choice !" << std::endl;
104                 choice = -1;
105             }
106
107             return choice;
108         }
109
110         void onResourceModelChanged(const std::string &uri,
111                                     const SimulatorResourceModel &resModel)
112         {
113             std::cout << "[callback] Resource model is changed URI: " << uri.c_str() << " Count : " <<
114                       resModel.size() << std::endl;
115             std::cout << "#### Modified attributes are ####" << std::endl;
116             for (auto & attribute : resModel.getAttributes())
117             {
118                 std::cout << attribute.second.getName() << " :  " << attribute.second.valueToString().c_str() <<
119                           std::endl;
120             }
121             std::cout << "########################" << std::endl;
122         }
123
124         void simulateResource()
125         {
126             SimulatorResourceServer::ResourceModelChangedCB callback = std::bind(
127                         &SimLightResource::onResourceModelChanged, this, std::placeholders::_1, std::placeholders::_2);
128             SimulatorResourceServerPtr resource = SimulatorManager::getInstance()->createResource("", callback);
129             if (NULL == resource.get())
130                 std::cout << "Failed to create resource" << std::endl;
131
132             m_resources.push_back(resource);
133             std::cout << "Resource created successfully! URI= " << resource->getURI().c_str() << std::endl;
134         }
135
136         void deleteResource()
137         {
138             int choice = -1;
139             std::cout << "1. Delete single resource" << std::endl;
140             std::cout << "2. Delete resources on resource types" << std::endl;
141             std::cout << "3. Delete all resources" << std::endl;
142
143             std::cout << "Enter your choice: ";
144             std::cin >> choice;
145             if (choice < 1 || choice > 3)
146             {
147                 std::cout << "Invalid choice !" << std::endl;
148                 return;
149             }
150
151             switch (choice)
152             {
153                 case 1:
154                     {
155                         int index = selectResource();
156                         if (-1 == index)
157                             return;
158
159                         if (SIMULATOR_SUCCESS == SimulatorManager::getInstance()->deleteResource(m_resources[index - 1]))
160                         {
161                             std::cout << "Resource deleted successfully! " << std::endl;
162                             m_resources.erase(m_resources.begin() + (index - 1));
163                         }
164                         else
165                         {
166                             std::cout << "Failed to delete resource!" << std::endl;
167                         }
168                     } break;
169                 case 2:
170                     {
171                         std::string resourceType;
172                         std::cout  << "Enter resource type:  ";
173                         std::cin >> resourceType;
174                         if (resourceType.empty())
175                         {
176                             std::cout << "Invalid resource type!" << std::endl;
177                             break;
178                         }
179
180                         if (SIMULATOR_SUCCESS == SimulatorManager::getInstance()->deleteResources(resourceType))
181                         {
182                             std::cout << "Resources of type \"" << resourceType << "\"" << " deleted successfully! " <<
183                                       std::endl;
184                             std::vector<SimulatorResourceServerPtr>::iterator ite = m_resources.begin();
185                             while (ite != m_resources.end())
186                             {
187                                 if (!resourceType.compare((*ite)->getResourceType()))
188                                 {
189                                     ite = m_resources.erase(ite);
190                                     continue;
191                                 }
192                                 ite++;
193                             }
194                         }
195                         else
196                         {
197                             std::cout << "Failed to delete resources of type \"" << resourceType << "\"!" << std::endl;
198                         }
199                     } break;
200                 case 3:
201                     {
202                         if (SIMULATOR_SUCCESS == SimulatorManager::getInstance()->deleteResources())
203                         {
204                             std::cout << "All resources deleted successfully! " << std::endl;
205                             m_resources.clear();
206                         }
207                         else
208                         {
209                             std::cout << "Failed to delete all resources!" << std::endl;
210                         }
211                     } break;
212             }
213
214         }
215
216         void updateAttributePower()
217         {
218             int index = selectResource();
219             if (-1 == index)
220                 return;
221
222             SimulatorResourceServerPtr resource = m_resources[index - 1];
223             SimulatorResourceModel resModel = resource->getModel();
224             SimulatorResourceModel::Attribute powerAttribute;
225             resModel.getAttribute("power", powerAttribute);
226
227             int allowedValuesSize = powerAttribute.getAllowedValuesSize();
228             if (0 == allowedValuesSize)
229             {
230                 std::cout << "This attribute does not have allowed values!" << std::endl;
231                 return;
232             }
233
234             std::cout << "Setting the new values from allowed values list to power attribute" << std::endl;
235             // Update all possible values from allowed values
236             for (int index = 0; index < allowedValuesSize; index++)
237             {
238                 // Update the new value and display the resource model after modifying
239                 resource->updateAttributeFromAllowedValues("power", index);
240                 std::cout << "Attribute value is modified ####" << std::endl;
241
242                 // Display the resource to user to verify the changed attribute value
243                 displayResource(resource);
244                 std::cout << std::endl << std::endl;
245
246                 // Get user input for continuing this operation
247                 if ((index + 1) < allowedValuesSize)
248                 {
249                     int choice;
250                     std::cout << "Would you like to continue the attribute values changing process? (1/0): ";
251                     std::cin >> choice;
252                     if (0 == choice)
253                         break;
254                 }
255             }
256
257             std::cout << "All the allowed values are tried!" << std::endl;
258         }
259
260         void updateAttributeIntensity()
261         {
262             int index = selectResource();
263             if (-1 == index)
264                 return;
265
266             SimulatorResourceServerPtr resource = m_resources[index - 1];
267             SimulatorResourceModel resModel = resource->getModel();
268             SimulatorResourceModel::Attribute intensityAttribute;
269             resModel.getAttribute("intensity", intensityAttribute);
270
271             int allowedValuesSize = intensityAttribute.getAllowedValuesSize();
272             if (0 == allowedValuesSize)
273             {
274                 std::cout << "This attribute does not have allowed values!" << std::endl;
275                 return;
276             }
277
278             std::cout << "Setting the new values from allowed values list to intensity attribute" << std::endl;
279             // Update all possible values from allowed values
280             for (int index = 0; index < allowedValuesSize; index++)
281             {
282                 // Update the new value and display the resource model after modifying
283                 resource->updateAttributeFromAllowedValues("intensity", index);
284                 std::cout << "Attribute value is modified ####" << std::endl;
285
286                 // Display the resource to user to verify the changed attribute value
287                 displayResource(resource);
288                 std::cout << std::endl << std::endl;
289
290                 // Get user input for continuing this operation
291                 if ((index + 1) < allowedValuesSize)
292                 {
293                     int choice;
294                     std::cout << "Would you like to continue the attribute values changing process? (1/0): ";
295                     std::cin >> choice;
296                     if (0 == choice)
297                         break;
298                 }
299             }
300
301             std::cout << "All the allowed values are tried!" << std::endl;
302         }
303
304         void displayResource()
305         {
306             int index = selectResource();
307             if (-1 == index)
308                 return;
309
310             SimulatorResourceServerPtr resource = m_resources[index - 1];
311             displayResource(resource);
312         }
313
314         void displayResource(SimulatorResourceServerPtr resource)
315         {
316             std::cout << "#############################" << std::endl;
317             std::cout << "Name: " << resource->getName().c_str() << std::endl;
318             std::cout << "URI: " << resource->getURI().c_str() << std::endl;
319             std::cout << "R. Type: " << resource->getResourceType().c_str() << std::endl;
320             std::cout << "I. Type: " << resource->getInterfaceType().c_str() << std::endl;
321
322             // Attributes
323             SimulatorResourceModel resModel = resource->getModel();
324             std::map<std::string, SimulatorResourceModel::Attribute> attributes = resModel.getAttributes();
325             std::cout << "##### Attributes [" << attributes.size() << "]" << std::endl;
326             for (auto & attribute : attributes)
327             {
328                 std::cout << (attribute.second).getName() << " :  {" << std::endl;
329                 std::cout << "value: " << (attribute.second).valueToString().c_str() << std::endl;
330                 int min, max;
331                 (attribute.second).getRange(min, max);
332                 std::cout << "min: " << min << std::endl;
333                 std::cout << "max: " << max << std::endl;
334                 std::cout << "allowed values : " << (attribute.second).allowedValuesToString() << std::endl;
335                 std::cout << "}" << std::endl << std::endl;
336             }
337             std::cout << "#############################" << std::endl;
338         }
339
340         void onUpdateAutomationCompleted(const std::string &uri,
341                                          const int id)
342         {
343             std::cout << "Update automation is completed [URI: " << uri.c_str() << "  AutomationID: " <<
344                       id << "] ###" << std::endl;
345         }
346
347         void automateResourceUpdate()
348         {
349             int index = selectResource();
350             if (-1 == index)
351                 return;
352
353             AutomationType type = AutomationType::NORMAL;
354             int choice = 0;
355             std::cout << "Press 1 if you want recurrent automation: ";
356             std::cin >> choice;
357             if (1 == choice)
358                 type = AutomationType::RECURRENT;
359
360             int id;
361             if (SIMULATOR_SUCCESS != m_resources[index - 1]->startUpdateAutomation(type,
362                     std::bind(&SimLightResource::onUpdateAutomationCompleted, this, std::placeholders::_1,
363                               std::placeholders::_2),
364                     id))
365                 std::cout << "startUpdateAutomation() returned error!" << std::endl;
366             else
367                 std::cout << "startUpdateAutomation() returned succces : " << id << std::endl;
368         }
369
370         void automateAttributeUpdate()
371         {
372             int index = selectResource();
373             if (-1 == index)
374                 return;
375
376             SimulatorResourceServerPtr resource = m_resources[index - 1];
377             SimulatorResourceModel resModel = resource->getModel();
378             std::map<std::string, SimulatorResourceModel::Attribute> attributes = resModel.getAttributes();
379             int size = 0;
380             for (auto & attribute : attributes)
381             {
382                 std::cout << ++size << ": " << attribute.first.c_str() << std::endl;
383             }
384
385             if (0 == size)
386             {
387                 std::cout << "This resource doest not contain any attributes!" << std::endl;
388                 return;
389             }
390
391             int choice = -1;
392             std::cout << "Select the attribute which you want to automate for updation: " << std::endl;
393             std::cin >> choice;
394             if (choice < 0 || choice > size)
395             {
396                 std::cout << "Invalid selection!" << std::endl;
397                 return;
398             }
399
400             int count = 0;
401             std::string attributeName;
402             for (auto & attribute : attributes)
403             {
404                 if (count == choice - 1)
405                 {
406                     attributeName = attribute.first;
407                     break;
408                 }
409
410                 count++;
411             }
412
413             AutomationType type = AutomationType::NORMAL;
414             std::cout << "Press 1 if you want recurrent automation: ";
415             std::cin >> choice;
416             if (1 == choice)
417                 type = AutomationType::RECURRENT;
418
419             std::cout << "Requesting attribute automation for " << attributeName.c_str() << std::endl;
420             int id;
421             if (SIMULATOR_SUCCESS != resource->startUpdateAutomation(attributeName, type,
422                     std::bind(&SimLightResource::onUpdateAutomationCompleted, this, std::placeholders::_1,
423                               std::placeholders::_2),
424                     id))
425                 std::cout << "startUpdateAutomation() returned error!" << std::endl;
426             else
427                 std::cout << "startUpdateAutomation() returned succces : " << id << std::endl;
428         }
429
430         void stopAutomation()
431         {
432             int index = selectResource();
433             if (-1 == index)
434                 return;
435
436             SimulatorResourceServerPtr resource = m_resources[index - 1];
437
438             // Select the automation to stop
439             std::vector<int> ids;
440             {
441                 std::vector<int> rids = resource->getResourceAutomationIds();
442                 std::vector<int> aids = resource->getAttributeAutomationIds();
443                 ids.insert(ids.end(), rids.begin(), rids.end());
444                 ids.insert(ids.end(), aids.begin(), aids.end());
445             }
446
447             if (!ids.size())
448             {
449                 std::cout << "No automation operation is going on this resource right now!" << std::endl;
450                 return;
451             }
452
453             for (auto & id : ids)
454                 std::cout <<  id  << " ";
455
456             int automationid;
457             std::cout << "\nEnter automation id: " << std::endl;
458             std::cin >> automationid;
459             resource->stopUpdateAutomation(automationid);
460         }
461
462     private:
463         std::vector<SimulatorResourceServerPtr> m_resources;
464 };
465
466 void printMainMenu()
467 {
468     std::cout << "############### MAIN MENU###############" << std::endl;
469     std::cout << "1. Test simulation of light resource" << std::endl;
470     std::cout << "2. Set Logger" << std::endl;
471     std::cout << "3. Help" << std::endl;
472     std::cout << "0. Exit" << std::endl;
473     std::cout << "######################################" << std::endl;
474 }
475
476 void setLogger()
477 {
478     std::cout << "1. Default console logger" << std::endl;
479     std::cout << "2. Default file logger" << std::endl;
480     std::cout << "3. custom logger" << std::endl;
481
482     int choice = -1;
483     std::cin >> choice;
484     if (choice <= 0 || choice > 3)
485     {
486         std::cout << "Invalid selection !" << std::endl;
487         return;
488     }
489
490     switch (choice)
491     {
492         case 1:
493             {
494                 if (false == SimulatorManager::getInstance()->setDefaultConsoleLogger())
495                     std::cout << "Failed to set the default console logger" << std::endl;
496             } break;
497         case 2:
498             {
499                 std::string filePath;
500                 std::cout << "Enter the file path (without file name) : ";
501                 std::cin >> filePath;
502                 if (false == SimulatorManager::getInstance()->setDefaultFileLogger(filePath))
503                     std::cout << "Failed to set default file logger" << std::endl;
504             } break;
505         case 3: SimulatorManager::getInstance()->setLogger(gAppLogger);
506     }
507 }
508
509 int main(void)
510 {
511     SimLightResource lightResource;
512
513     printMainMenu();
514     bool cont = true;
515     while (cont == true)
516     {
517         int choice = -1;
518         std::cout << "Enter your choice: ";
519         std::cin >> choice;
520         if (choice < 0 || choice > 3)
521         {
522             std::cout << "Invaild choice !" << std::endl; continue;
523         }
524
525         switch (choice)
526         {
527             case 1: lightResource.startTest();
528                 std::cout << "Welcome back to main menu !" << std::endl;
529                 break;
530             case 2: setLogger(); break;
531             case 3: printMainMenu(); break;
532             case 0: cont = false;
533         }
534     }
535
536     std::cout << "Terminating test !!!" << std::endl;
537 }