Collection resource not notifying its updated model when child resource is added...
[platform/upstream/iotivity.git] / service / simulator / examples / server / simulator_server.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 std::vector<SimulatorSingleResourceSP> g_singleResources;
24 std::vector<SimulatorCollectionResourceSP> g_collectionResources;
25
26 std::string getPropertyTypeString(SimulatorResourceModel::AttributeProperty::Type type)
27 {
28     switch(type)
29     {
30         case SimulatorResourceModel::AttributeProperty::Type::RANGE:
31             return "RANGE";
32         case SimulatorResourceModel::AttributeProperty::Type::VALUE_SET:
33             return "VALUE_SET";
34         default:
35             break;
36     }
37
38     return "UNKNOWN";
39 }
40
41 class AppLogger : public ILogger
42 {
43     public:
44         void write(std::string time, ILogger::Level level, std::string message)
45         {
46             std::cout << "[APPLogger] " << time << " " << ILogger::getString(level) << " "
47                       << message;
48         }
49 };
50 std::shared_ptr<AppLogger> gAppLogger(new AppLogger());
51
52 int selectResource()
53 {
54     if (0 == g_singleResources.size())
55     {
56         std::cout << "No resouces!" << std::endl;
57         return -1;
58     }
59
60     int index = 1;
61     for (auto & resource : g_singleResources)
62     {
63         std::cout << index++ << ": " << resource->getURI().c_str() << std::endl;
64     }
65
66     int choice = -1;
67     std::cout << "Choose the resource: ";
68     std::cin >> choice;
69
70     if (choice < 1 || choice > index - 1)
71     {
72         std::cout << "Invalid choice !" << std::endl;
73         choice = -1;
74     }
75
76     return choice;
77 }
78
79 void simulateResource()
80 {
81     try
82     {
83         // Resource model change callback
84         SimulatorResource::ResourceModelChangedCallback modelChangeCB =
85         [](const std::string &uri, SimulatorResourceModel &resModel)
86         {
87             std::cout << "[callback] Resource model is changed URI: " << uri.c_str() << std::endl;
88             std::cout << "#### Modified attributes are ####" << std::endl;
89             std::cout << "#### Updated resource model ####" << std::endl;
90             std::cout << resModel.toString() << std::endl;
91             std::cout << "########################" << std::endl;
92         };
93
94         // Observer added/removed callback
95         SimulatorResource::ObserverCallback observerCB =
96         [] (const std::string &uri, ObservationStatus state, const ObserverInfo &observerInfo)
97         {
98             std::cout << "[callback] Observer notification received..." << uri << std::endl;
99
100             std::ostringstream out;
101             out << "ID:  " << (int) observerInfo.id << std::endl;
102             out << " [address: " << observerInfo.address << " port: " << observerInfo.port
103                 << "]" << std::endl;
104             std::cout << out.str();
105         };
106
107         // Get the RAML file path from user
108         std::string configPath;
109         std::cout << "Enter RAML path: ";
110         std::cin>>configPath;
111
112         SimulatorResourceSP resource =
113             SimulatorManager::getInstance()->createResource(configPath);
114
115         // Add resource to appropriate list
116         if (SimulatorResource::Type::SINGLE_RESOURCE == resource->getType())
117         {
118             std::cout << "Single type resource created [URI:  " << resource->getURI() << " ]" << std::endl;
119             SimulatorSingleResourceSP singleRes =
120                 std::dynamic_pointer_cast<SimulatorSingleResource>(resource);
121             singleRes->setModelChangeCallback(modelChangeCB);
122             singleRes->setObserverCallback(observerCB);
123             g_singleResources.push_back(singleRes);
124         }
125         else
126         {
127             std::cout << "Collection type resource created [URI:  " << resource->getURI() << " ]" << std::endl;
128             SimulatorCollectionResourceSP collectionRes =
129                 std::dynamic_pointer_cast<SimulatorCollectionResource>(resource);
130             collectionRes->setObserverCallback(observerCB);
131             g_collectionResources.push_back(collectionRes);
132         }
133     }
134     catch (InvalidArgsException &e)
135     {
136         std::cout << "InvalidArgsException occured [code : " << e.code() << " Details: "
137                   << e.what() << "]" << std::endl;
138     }
139     catch (SimulatorException &e)
140     {
141         std::cout << "SimulatorException occured [code : " << e.code() << " Details: "
142                   << e.what() << "]" << std::endl;
143     }
144 }
145
146 void displayResource()
147 {
148     int index = selectResource();
149     if (-1 == index)
150         return;
151
152     SimulatorSingleResourceSP resource = g_singleResources[index - 1];
153
154     std::cout << "#############################" << std::endl;
155     std::cout << "Name: " << resource->getName() << std::endl;
156     std::cout << "URI: " << resource->getURI() << std::endl;
157     std::cout << "Resource type: " << resource->getResourceType() << std::endl;
158     std::cout << "Interface type:";
159     for (auto &interfaceType : resource->getInterface())
160         std::cout << " " << interfaceType << std::endl;
161
162     // Attributes
163     SimulatorResourceModel resModel = resource->getResourceModel();
164     std::map<std::string, SimulatorResourceModel::Attribute> attributes =
165         resModel.getAttributes();
166     std::cout << "##### Attributes [" << attributes.size() << "]" << std::endl;
167     for (auto & attribute : attributes)
168     {
169         std::cout << (attribute.second).getName() << " :  {" << std::endl;
170         std::cout << "value: " << (attribute.second).toString() << std::endl;
171         SimulatorResourceModel::AttributeProperty prop = (attribute.second).getProperty();
172         std::cout << "Supported values given by : " << getPropertyTypeString(prop.type()) << std::endl;
173         if (SimulatorResourceModel::AttributeProperty::Type::RANGE == prop.type())
174         {
175             std::cout << "Min: " << prop.min() << std::endl;
176             std::cout << "Max: " << prop.max() << std::endl;
177         }
178         else if (SimulatorResourceModel::AttributeProperty::Type::VALUE_SET == prop.type())
179         {
180             std::cout << "Value set: " << prop.valueSetToString() << std::endl;
181         }
182
183         std::cout << "}" << std::endl << std::endl;
184     }
185     std::cout << "#############################" << std::endl;
186 }
187
188 void startResource()
189 {
190     int index = selectResource();
191     if (-1 == index)
192         return;
193
194     SimulatorSingleResourceSP resource = g_singleResources[index - 1];
195     resource->start();
196     std::cout << "Resource started!" << std::endl;
197 }
198
199 void stopResource()
200 {
201     int index = selectResource();
202     if (-1 == index)
203         return;
204
205     SimulatorSingleResourceSP resource = g_singleResources[index - 1];
206     resource->stop();
207     std::cout << "Resource stopped!" << std::endl;
208 }
209
210 void automateResourceUpdate()
211 {
212     updateCompleteCallback callback = [](const std::string &uri, const int id)
213     {
214         std::cout << "Update automation is completed [URI: " << uri
215                   << "  AutomationID: " << id << "] ###" << std::endl;
216     };
217
218     int index = selectResource();
219     if (-1 == index)
220         return;
221
222     AutomationType type = AutomationType::NORMAL;
223     int choice = 0;
224     std::cout << "Press 1 if you want recurrent automation: ";
225     std::cin >> choice;
226     if (1 == choice)
227         type = AutomationType::RECURRENT;
228
229     try
230     {
231         int id = g_singleResources[index - 1]->startResourceUpdation(type, -1, callback);
232
233         std::cout << "startUpdateAutomation() returned succces : " << id << std::endl;
234     }
235     catch (SimulatorException &e)
236     {
237         std::cout << "SimulatorException occured [code : " << e.code() << " Details: " <<
238                   e.what() << "]" << std::endl;
239     }
240 }
241
242 void automateAttributeUpdate()
243 {
244     updateCompleteCallback callback = [](const std::string &uri, const int id)
245     {
246         std::cout << "Update automation is completed [URI: " << uri
247                   << "  AutomationID: " << id << "] ###" << std::endl;
248     };
249
250     int index = selectResource();
251     if (-1 == index)
252         return;
253
254     SimulatorSingleResourceSP resource = g_singleResources[index - 1];
255     SimulatorResourceModel resModel = resource->getResourceModel();
256     std::map<std::string, SimulatorResourceModel::Attribute> attributes =
257         resModel.getAttributes();
258     int size = 0;
259     for (auto & attribute : attributes)
260     {
261         std::cout << ++size << ": " << attribute.first.c_str() << std::endl;
262     }
263
264     if (0 == size)
265     {
266         std::cout << "This resource doest not contain any attributes!" << std::endl;
267         return;
268     }
269
270     int choice = -1;
271     std::cout << "Select the attribute which you want to automate for updation: " <<
272               std::endl;
273     std::cin >> choice;
274     if (choice < 0 || choice > size)
275     {
276         std::cout << "Invalid selection!" << std::endl;
277         return;
278     }
279
280     int count = 0;
281     std::string attributeName;
282     for (auto & attribute : attributes)
283     {
284         if (count == choice - 1)
285         {
286             attributeName = attribute.first;
287             break;
288         }
289
290         count++;
291     }
292
293     AutomationType type = AutomationType::NORMAL;
294     std::cout << "Press 1 if you want recurrent automation: ";
295     std::cin >> choice;
296     if (1 == choice)
297         type = AutomationType::RECURRENT;
298
299     std::cout << "Requesting attribute automation for " << attributeName <<
300               std::endl;
301
302     try
303     {
304
305         int id = resource->startAttributeUpdation(attributeName, type, -1, callback);
306         std::cout << "startUpdateAutomation() returned succces : " << id << std::endl;
307     }
308     catch (SimulatorException &e)
309     {
310         std::cout << "SimulatorException occured [Error: " << e.code() << " Details: " <<
311                   e.what() << "]" << std::endl;
312     }
313 }
314
315 void stopAutomation()
316 {
317     int index = selectResource();
318     if (-1 == index)
319         return;
320
321     SimulatorSingleResourceSP resource = g_singleResources[index - 1];
322
323     // Select the automation to stop
324     std::vector<int> ids;
325     {
326         std::vector<int> rids = resource->getResourceUpdationIds();
327         std::vector<int> aids = resource->getAttributeUpdationIds();
328         ids.insert(ids.end(), rids.begin(), rids.end());
329         ids.insert(ids.end(), aids.begin(), aids.end());
330     }
331
332     if (!ids.size())
333     {
334         std::cout << "No automation operation is going on this resource right now!" <<
335                   std::endl;
336         return;
337     }
338
339     for (auto & id : ids)
340     {
341         std::cout <<  id  << " ";
342         resource->stopUpdation(id);
343     }
344 }
345
346 void getObservers()
347 {
348     int index = selectResource();
349     if (-1 == index)
350         return;
351
352     SimulatorSingleResourceSP resource = g_singleResources[index - 1];
353
354     std::vector<ObserverInfo> observersList = resource->getObserversList();
355
356     std::cout << "##### Number of Observers [" << observersList.size() << "]" << std::endl;
357     for (auto & observerInfo : observersList)
358     {
359         std::cout << " ID :  " << (int) observerInfo.id << " [address: " <<
360                   observerInfo.address << " port: " << observerInfo.port << "]" << std::endl;
361     }
362     std::cout << "########################" << std::endl;
363 }
364
365 void printMainMenu()
366 {
367     std::cout << "############### MAIN MENU###############" << std::endl;
368     std::cout << "1. Simulate resource" << std::endl;
369     std::cout << "2. Display resource information" << std::endl;
370     std::cout << "3. Start resource" << std::endl;
371     std::cout << "4. Stop resource" << std::endl;
372     std::cout << "5. Automate resource update" << std::endl;
373     std::cout << "6. Automate attributes update" << std::endl;
374     std::cout << "7. Stop Automation" << std::endl;
375     std::cout << "8. Get Observers of a resource" << std::endl;
376     std::cout << "9. Set Logger" << std::endl;
377     std::cout << "10. Help" << std::endl;
378     std::cout << "0. Exit" << std::endl;
379     std::cout << "######################################" << std::endl;
380 }
381
382 void setLogger()
383 {
384     std::cout << "1. Default console logger" << std::endl;
385     std::cout << "2. Default file logger" << std::endl;
386     std::cout << "3. custom logger" << std::endl;
387
388     int choice = -1;
389     std::cin >> choice;
390     if (choice <= 0 || choice > 3)
391     {
392         std::cout << "Invalid selection !" << std::endl;
393         return;
394     }
395
396     switch (choice)
397     {
398         case 1:
399             {
400                 if (false == SimulatorManager::getInstance()->setConsoleLogger())
401                     std::cout << "Failed to set the default console logger" << std::endl;
402             } break;
403         case 2:
404             {
405                 std::string filePath;
406                 std::cout << "Enter the file path (without file name) : ";
407                 std::cin >> filePath;
408                 if (false == SimulatorManager::getInstance()->setFileLogger(filePath))
409                     std::cout << "Failed to set default file logger" << std::endl;
410             } break;
411         case 3: SimulatorManager::getInstance()->setLogger(gAppLogger);
412     }
413 }
414
415 int main(int argc, char *argv[])
416 {
417     printMainMenu();
418     bool cont = true;
419     while (cont == true)
420     {
421         int choice = -1;
422         std::cout << "Enter your choice: ";
423         std::cin >> choice;
424         if (choice < 0 || choice > 10)
425         {
426             std::cout << "Invaild choice !" << std::endl; continue;
427         }
428
429         switch (choice)
430         {
431             case 1 : simulateResource(); break;
432             case 2 : displayResource(); break;
433             case 3 : startResource(); break;
434             case 4 : stopResource(); break;
435             case 5 : automateResourceUpdate(); break;
436             case 6 : automateAttributeUpdate(); break;
437             case 7 : stopAutomation(); break;
438             case 8 : getObservers(); break;
439             case 9: setLogger(); break;
440             case 10: printMainMenu(); break;
441             case 0: cont = false;
442         }
443     }
444
445     std::cout << "Terminating test !!!" << std::endl;
446 }