Imported Upstream version 1.0.0
[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) << " "
29                       << message;
30         }
31 };
32 std::shared_ptr<AppLogger> gAppLogger(new AppLogger());
33
34 class SimLightResource
35 {
36     public:
37         void startTest(std::string &configPath)
38         {
39             printMenu();
40             bool cont = true;
41             while (cont)
42             {
43                 int choice = -1;
44                 std::cout << "Enter your choice: ";
45                 std::cin >> choice;
46                 if (choice < 0 || choice > 10)
47                 {
48                     std::cout << "Invaild choice !" << std::endl; continue;
49                 }
50
51                 switch (choice)
52                 {
53                     case 1 : simulateResource(configPath); break;
54                     case 2 : displayResource(); break;
55                     case 3 :
56                         try
57                         {
58                             deleteResource();
59                         }
60                         catch (InvalidArgsException &e)
61                         {
62                             std::cout << "InvalidArgsException occured [code : " << e.code() <<
63                                       " Detail: " << e.what() << "]" << std::endl;
64                         }
65                         break;
66                     case 4 : updateAttributePower(); break;
67                     case 5 : updateAttributeIntensity(); break;
68                     case 6 : automateResourceUpdate(); break;
69                     case 7 : automateAttributeUpdate(); break;
70                     case 8 : stopAutomation(); break;
71                     case 9 : getObservers(); break;
72                     case 10: printMenu(); break;
73                     case 0: cont = false;
74                 }
75             }
76         }
77
78     private:
79         void printMenu()
80         {
81             std::cout << "########### LIGHT RESOURCE TESTING ###########" << std::endl;
82             std::cout << "1. Simulate resource" << std::endl;
83             std::cout << "2. Display resource information" << std::endl;
84             std::cout << "3. Delete resource" << std::endl;
85             std::cout << "4. Update attribute \"power\"" << std::endl;
86             std::cout << "5. Update attribute \"intensity\"" << std::endl;
87             std::cout << "6. Automate resource update" << std::endl;
88             std::cout << "7. Automate attributes update" << std::endl;
89             std::cout << "8. Stop Automation" << std::endl;
90             std::cout << "9. Get Observers of a resource" << std::endl;
91             std::cout << "10: Help" << std::endl;
92             std::cout << "0. Exit" << std::endl;
93             std::cout << "#######################################" << std::endl;
94         }
95
96         int selectResource()
97         {
98             if (0 == m_resources.size())
99             {
100                 std::cout << "No resouces!" << std::endl;
101                 return -1;
102             }
103
104             int index = 1;
105             for (auto & resource : m_resources)
106             {
107                 std::cout << index++ << ": " << resource->getURI().c_str() << std::endl;
108             }
109
110             int choice = -1;
111             std::cout << "Choose the resource: ";
112             std::cin >> choice;
113
114             if (choice < 1 || choice > index - 1)
115             {
116                 std::cout << "Invalid choice !" << std::endl;
117                 choice = -1;
118             }
119
120             return choice;
121         }
122
123         void onResourceModelChanged(const std::string &uri,
124                                     const SimulatorResourceModel &resModel)
125         {
126             std::cout << "[callback] Resource model is changed URI: " << uri.c_str()
127                       << " Count : " << resModel.size() << std::endl;
128             std::cout << "#### Modified attributes are ####" << std::endl;
129             for (auto & attribute : resModel.getAttributes())
130             {
131                 std::cout << attribute.second.getName() << " :  "
132                           << attribute.second.valueToString().c_str() << std::endl;
133             }
134             std::cout << "########################" << std::endl;
135         }
136
137         void simulateResource(std::string &configPath)
138         {
139             SimulatorResourceServer::ResourceModelChangedCB callback = std::bind(
140                         &SimLightResource::onResourceModelChanged, this, std::placeholders::_1,
141                         std::placeholders::_2);
142
143             try
144             {
145                 SimulatorResourceServerSP resource =
146                     SimulatorManager::getInstance()->createResource(configPath, callback);
147                 m_resources.push_back(resource);
148                 std::cout << "Resource created successfully! URI= " << resource->getURI().c_str()
149                           << std::endl;
150             }
151             catch (InvalidArgsException &e)
152             {
153                 std::cout << "InvalidArgsException occured [code : " << e.code() << " Detail: "
154                           << e.what() << "]" << std::endl;
155             }
156             catch (SimulatorException &e)
157             {
158                 std::cout << "SimulatorException occured [code : " << e.code() << " Detail: "
159                           << e.what() << "]" << std::endl;
160             }
161         }
162
163         void deleteResource()
164         {
165             int choice = -1;
166             std::cout << "1. Delete single resource" << std::endl;
167             std::cout << "2. Delete resources on resource types" << std::endl;
168             std::cout << "3. Delete all resources" << std::endl;
169
170             std::cout << "Enter your choice: ";
171             std::cin >> choice;
172             if (choice < 1 || choice > 3)
173             {
174                 std::cout << "Invalid choice !" << std::endl;
175                 return;
176             }
177
178             switch (choice)
179             {
180                 case 1:
181                     {
182                         int index = selectResource();
183                         if (-1 == index)
184                             return;
185
186                         SimulatorManager::getInstance()->deleteResource(m_resources[index - 1]);
187                         std::cout << "Resource deleted successfully! " << std::endl;
188                         m_resources.erase(m_resources.begin() + (index - 1));
189
190                     } break;
191
192                 case 2:
193                     {
194                         std::string resourceType;
195                         std::cout  << "Enter resource type:  ";
196                         std::cin >> resourceType;
197                         if (resourceType.empty())
198                         {
199                             std::cout << "Invalid resource type!" << std::endl;
200                             break;
201                         }
202
203                         try
204                         {
205                             SimulatorManager::getInstance()->deleteResource(resourceType);
206                             std::cout << "Resources of type \"" << resourceType << "\"" <<
207                                       " deleted successfully! " << std::endl;
208                             std::vector<SimulatorResourceServerSP>::iterator ite = m_resources.begin();
209                             while (ite != m_resources.end())
210                             {
211                                 if (!resourceType.compare((*ite)->getResourceType()))
212                                 {
213                                     ite = m_resources.erase(ite);
214                                     continue;
215                                 }
216                                 ite++;
217                             }
218                         }
219                         catch (InvalidArgsException &e)
220                         {
221                             std::cout << "InvalidArgsException occured [code : " << e.code()
222                                       << " Detail: " << e.what() << "]" << std::endl;
223                         }
224                         catch (SimulatorException &e)
225                         {
226                             std::cout << "SimulatorException occured [code : " << e.code()
227                                       << " Detail: " << e.what() << "]" << std::endl;
228                         }
229                     } break;
230
231                 case 3:
232                     {
233                         SimulatorManager::getInstance()->deleteResource();
234                         std::cout << "All resources deleted successfully! " << std::endl;
235                         m_resources.clear();
236                     } break;
237             }
238
239         }
240
241         void updateAttributePower()
242         {
243             int index = selectResource();
244             if (-1 == index)
245                 return;
246
247             SimulatorResourceServerSP resource = m_resources[index - 1];
248             SimulatorResourceModel resModel = resource->getModel();
249             SimulatorResourceModel::Attribute powerAttribute;
250             resModel.getAttribute("power", powerAttribute);
251
252             int allowedValuesSize = powerAttribute.getAllowedValuesSize();
253             if (0 == allowedValuesSize)
254             {
255                 std::cout << "This attribute does not have allowed values!" << std::endl;
256                 return;
257             }
258
259             std::cout << "Setting the new values from allowed values list to power attribute" <<
260                       std::endl;
261             // Update all possible values from allowed values
262             for (int index = 0; index < allowedValuesSize; index++)
263             {
264                 // Update the new value and display the resource model after modifying
265                 resource->updateFromAllowedValues("power", index);
266                 std::cout << "Attribute value is modified ####" << std::endl;
267
268                 // Display the resource to user to verify the changed attribute value
269                 displayResource(resource);
270                 std::cout << std::endl << std::endl;
271
272                 // Get user input for continuing this operation
273                 if ((index + 1) < allowedValuesSize)
274                 {
275                     int choice;
276                     std::cout << "Would you like to change attribute value again ? (1/0): ";
277                     std::cin >> choice;
278                     if (0 == choice)
279                         break;
280                 }
281             }
282
283             std::cout << "All the allowed values are tried!" << std::endl;
284         }
285
286         void updateAttributeIntensity()
287         {
288             int index = selectResource();
289             if (-1 == index)
290                 return;
291
292             SimulatorResourceServerSP resource = m_resources[index - 1];
293             SimulatorResourceModel resModel = resource->getModel();
294             SimulatorResourceModel::Attribute intensityAttribute;
295             resModel.getAttribute("intensity", intensityAttribute);
296
297             int min, max;
298             intensityAttribute.getRange(min, max);
299             if (!min && !max)
300             {
301                 std::cout << "This attribute does not have range!" << std::endl;
302                 return;
303             }
304
305             std::cout << "Setting the new values from allowed values list to intensity attribute"
306                       << std::endl;
307             // Update all possible values from allowed values
308             for (int index = min; index <= max; index++)
309             {
310                 // Update the new value and display the resource model after modifying
311                 resource->updateAttributeValue("intensity", index);
312                 std::cout << "Attribute value is modified ####" << std::endl;
313
314                 // Display the resource to user to verify the changed attribute value
315                 displayResource(resource);
316                 std::cout << std::endl << std::endl;
317
318                 // Get user input for continuing this operation
319                 if ((index + 1) <= max)
320                 {
321                     int choice;
322                     std::cout << "Would you like to change attribute value again ? (1/0): ";
323                     std::cin >> choice;
324                     if (0 == choice)
325                         break;
326                 }
327             }
328
329             std::cout << "All the allowed values are tried!" << std::endl;
330         }
331
332         void displayResource()
333         {
334             int index = selectResource();
335             if (-1 == index)
336                 return;
337
338             SimulatorResourceServerSP resource = m_resources[index - 1];
339             displayResource(resource);
340         }
341
342         void displayResource(SimulatorResourceServerSP resource)
343         {
344             std::cout << "#############################" << std::endl;
345             std::cout << "Name: " << resource->getName().c_str() << std::endl;
346             std::cout << "URI: " << resource->getURI().c_str() << std::endl;
347             std::cout << "R. Type: " << resource->getResourceType().c_str() << std::endl;
348             std::cout << "I. Type: " << resource->getInterfaceType().c_str() << std::endl;
349
350             // Attributes
351             SimulatorResourceModel resModel = resource->getModel();
352             std::map<std::string, SimulatorResourceModel::Attribute> attributes =
353                 resModel.getAttributes();
354             std::cout << "##### Attributes [" << attributes.size() << "]" << std::endl;
355             for (auto & attribute : attributes)
356             {
357                 std::cout << (attribute.second).getName() << " :  {" << std::endl;
358                 std::cout << "value: " << (attribute.second).valueToString().c_str() << std::endl;
359                 int min, max;
360                 (attribute.second).getRange(min, max);
361                 std::cout << "min: " << min << std::endl;
362                 std::cout << "max: " << max << std::endl;
363                 std::cout << "allowed values : ";
364                 std::cout << "[ ";
365                 for (auto & value : (attribute.second).allowedValuesToString())
366                     std::cout << value << " ";
367                 std::cout << "]" << std::endl;
368                 std::cout << "}" << std::endl << std::endl;
369             }
370             std::cout << "#############################" << std::endl;
371         }
372
373         void onUpdateAutomationCompleted(const std::string &uri,
374                                          const int id)
375         {
376             std::cout << "Update automation is completed [URI: " << uri.c_str()
377                       << "  AutomationID: " << id << "] ###" << std::endl;
378         }
379
380         void automateResourceUpdate()
381         {
382             int index = selectResource();
383             if (-1 == index)
384                 return;
385
386             AutomationType type = AutomationType::NORMAL;
387             int choice = 0;
388             std::cout << "Press 1 if you want recurrent automation: ";
389             std::cin >> choice;
390             if (1 == choice)
391                 type = AutomationType::RECURRENT;
392
393             try
394             {
395                 int id = m_resources[index - 1]->startUpdateAutomation(type,
396                          std::bind(&SimLightResource::onUpdateAutomationCompleted, this,
397                                    std::placeholders::_1, std::placeholders::_2));
398
399                 std::cout << "startUpdateAutomation() returned succces : " << id << std::endl;
400             }
401             catch (SimulatorException &e)
402             {
403                 std::cout << "SimulatorException occured [code : " << e.code() << " Detail: " <<
404                           e.what() << "]" << std::endl;
405             }
406         }
407
408         void automateAttributeUpdate()
409         {
410             int index = selectResource();
411             if (-1 == index)
412                 return;
413
414             SimulatorResourceServerSP resource = m_resources[index - 1];
415             SimulatorResourceModel resModel = resource->getModel();
416             std::map<std::string, SimulatorResourceModel::Attribute> attributes =
417                 resModel.getAttributes();
418             int size = 0;
419             for (auto & attribute : attributes)
420             {
421                 std::cout << ++size << ": " << attribute.first.c_str() << std::endl;
422             }
423
424             if (0 == size)
425             {
426                 std::cout << "This resource doest not contain any attributes!" << std::endl;
427                 return;
428             }
429
430             int choice = -1;
431             std::cout << "Select the attribute which you want to automate for updation: " <<
432                       std::endl;
433             std::cin >> choice;
434             if (choice < 0 || choice > size)
435             {
436                 std::cout << "Invalid selection!" << std::endl;
437                 return;
438             }
439
440             int count = 0;
441             std::string attributeName;
442             for (auto & attribute : attributes)
443             {
444                 if (count == choice - 1)
445                 {
446                     attributeName = attribute.first;
447                     break;
448                 }
449
450                 count++;
451             }
452
453             AutomationType type = AutomationType::NORMAL;
454             std::cout << "Press 1 if you want recurrent automation: ";
455             std::cin >> choice;
456             if (1 == choice)
457                 type = AutomationType::RECURRENT;
458
459             std::cout << "Requesting attribute automation for " << attributeName.c_str() <<
460                       std::endl;
461
462             try
463             {
464
465                 int id = resource->startUpdateAutomation(attributeName, type,
466                          std::bind(&SimLightResource::onUpdateAutomationCompleted, this,
467                                    std::placeholders::_1, std::placeholders::_2));
468                 std::cout << "startUpdateAutomation() returned succces : " << id << std::endl;
469             }
470             catch (SimulatorException &e)
471             {
472                 std::cout << "SimulatorException occured [Error: " << e.code() << " Details: " <<
473                           e.what() << "]" << std::endl;
474             }
475         }
476
477         void stopAutomation()
478         {
479             int index = selectResource();
480             if (-1 == index)
481                 return;
482
483             SimulatorResourceServerSP resource = m_resources[index - 1];
484
485             // Select the automation to stop
486             std::vector<int> ids;
487             {
488                 std::vector<int> rids = resource->getResourceAutomationIds();
489                 std::vector<int> aids = resource->getAttributeAutomationIds();
490                 ids.insert(ids.end(), rids.begin(), rids.end());
491                 ids.insert(ids.end(), aids.begin(), aids.end());
492             }
493
494             if (!ids.size())
495             {
496                 std::cout << "No automation operation is going on this resource right now!" <<
497                           std::endl;
498                 return;
499             }
500
501             for (auto & id : ids)
502                 std::cout <<  id  << " ";
503
504             int automationid;
505             std::cout << "\nEnter automation id: " << std::endl;
506             std::cin >> automationid;
507             resource->stopUpdateAutomation(automationid);
508         }
509
510         void onObserverChanged(const std::string &uri, ObservationStatus state,
511                                const ObserverInfo &observerInfo)
512         {
513             std::cout << "[callback] Observer notification received..." << uri.c_str() << std::endl;
514             std::ostringstream out;
515             out << "ID:  " << (int) observerInfo.id << std::endl;
516             out << " [address: " << observerInfo.address << " port: " << observerInfo.port
517                 << "]" << std::endl;
518             std::cout << out.str();
519         }
520
521         void getObservers()
522         {
523             int index = selectResource();
524             if (-1 == index)
525                 return;
526
527             SimulatorResourceServerSP resource = m_resources[index - 1];
528
529             SimulatorResourceServer::ObserverCB callback = std::bind(
530                         &SimLightResource::onObserverChanged, this, std::placeholders::_1,
531                         std::placeholders::_2, std::placeholders::_3);
532             resource->setObserverCallback(callback);
533
534             std::vector<ObserverInfo> observersList = resource->getObserversList();
535
536             std::cout << "##### Number of Observers [" << observersList.size() << "]" << std::endl;
537             for (auto & observerInfo : observersList)
538             {
539                 std::cout << " ID :  " << (int) observerInfo.id << " [address: " <<
540                           observerInfo.address << " port: " << observerInfo.port << "]" << std::endl;
541             }
542             std::cout << "########################" << std::endl;
543         }
544
545     private:
546         std::vector<SimulatorResourceServerSP> m_resources;
547 };
548
549 void printMainMenu()
550 {
551     std::cout << "############### MAIN MENU###############" << std::endl;
552     std::cout << "1. Test simulation of resource" << std::endl;
553     std::cout << "2. Set Logger" << std::endl;
554     std::cout << "3. Help" << std::endl;
555     std::cout << "0. Exit" << std::endl;
556     std::cout <<
557               "To set the Resource from RAML file, run the service provider with argument of Path of Raml File."
558               << std::endl;
559     std::cout <<
560               "Example: ./simulator-server PATH-TO-RAML-FILE"
561               << std::endl;
562     std::cout << "######################################" << std::endl;
563 }
564
565 void setLogger()
566 {
567     std::cout << "1. Default console logger" << std::endl;
568     std::cout << "2. Default file logger" << std::endl;
569     std::cout << "3. custom logger" << std::endl;
570
571     int choice = -1;
572     std::cin >> choice;
573     if (choice <= 0 || choice > 3)
574     {
575         std::cout << "Invalid selection !" << std::endl;
576         return;
577     }
578
579     switch (choice)
580     {
581         case 1:
582             {
583                 if (false == SimulatorManager::getInstance()->setConsoleLogger())
584                     std::cout << "Failed to set the default console logger" << std::endl;
585             } break;
586         case 2:
587             {
588                 std::string filePath;
589                 std::cout << "Enter the file path (without file name) : ";
590                 std::cin >> filePath;
591                 if (false == SimulatorManager::getInstance()->setFileLogger(filePath))
592                     std::cout << "Failed to set default file logger" << std::endl;
593             } break;
594         case 3: SimulatorManager::getInstance()->setLogger(gAppLogger);
595     }
596 }
597
598 int main(int argc, char *argv[])
599 {
600     std::string configPath = "";
601
602     if (argc == 2)
603     {
604         char *value = argv[1];
605         configPath.append(value);
606     }
607     else
608     {
609         configPath = "";
610     }
611     SimLightResource lightResource;
612
613     printMainMenu();
614     bool cont = true;
615     while (cont == true)
616     {
617         int choice = -1;
618         std::cout << "Enter your choice: ";
619         std::cin >> choice;
620         if (choice < 0 || choice > 3)
621         {
622             std::cout << "Invaild choice !" << std::endl; continue;
623         }
624
625         switch (choice)
626         {
627             case 1: lightResource.startTest(configPath);
628                 std::cout << "Welcome back to main menu !" << std::endl;
629                 break;
630             case 2: setLogger(); break;
631             case 3: printMainMenu(); break;
632             case 0: cont = false;
633         }
634     }
635
636     std::cout << "Terminating test !!!" << std::endl;
637 }