Merge branch 'master' into cloud-interface
[platform/upstream/iotivity.git] / service / resource-container / examples / ContainerSample.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 #if defined(__linux__)
22 #include <unistd.h>
23 #include <string.h>
24 #endif
25
26 #include "RCSResourceContainer.h"
27 #include "RCSBundleInfo.h"
28
29 #include <iostream>
30 #include <functional>
31 #include <limits>
32 #include <stdexcept>
33 #include <string>
34
35 using namespace OIC::Service;
36
37 namespace
38 {
39     typedef enum
40     {
41         START_RC = 1, STOP_RC,
42         ADD_SAMPLE_BUNDLE, START_SAMPLE_BUNDLE,
43         STOP_SAMPLE_BUNDLE, REMOVE_SAMPLE_BUNDLE,
44         ADD_SAMPLE_RESOURCE, REMOVE_SAMPLE_RESOURCE,
45         LIST_BUNDLES, LIST_RESOURCES,
46         EXIT = 11
47     } APPMenu;
48
49     struct CloseApp {};
50
51     const int MAX_PATH = 2048;
52
53     const std::string EXAMPLE_CONFIG_PATH = "/examples/ResourceContainerConfig.xml";
54     const std::string EXAMPLE_BUNDLE_ID = "oic.bundle.hueSample";
55     const std::string EXAMPLE_BUNDLE_URI = "/hueSample";
56     const std::string EXAMPLE_BUNDLE_PATH = "libHueBundle.so";
57     const std::string EXAMPLE_BUNDLE_ACTIVATOR = "huesample";
58     const std::string EXAMPLE_RESOURCE_URI = "/hue/light/sample";
59     const std::string EXAMPLE_RESOURCE_TYPE = "oic.r.light";
60     const std::string EXAMPLE_ADDRESS = "http://192.168.0.2/api/newdeveloper/lights/1";
61 };
62
63 bool g_bContainerStarted = false;
64 bool g_bSampleBundleStarted = false;
65 RCSResourceContainer *g_pResourceContainer = nullptr;
66
67 void getCurrentPath(std::string *pPath)
68 {
69     char buffer[MAX_PATH];
70
71     if (!pPath->empty())
72         pPath->clear();
73
74 #if defined(__linux__)
75     char *strPath = NULL;
76     int length = readlink("/proc/self/exe", buffer, MAX_PATH - 1);
77
78     if (length != -1)
79     {
80         buffer[length] = '\0';
81         strPath = strrchr(buffer, '/');
82
83         if (strPath != NULL)
84             *strPath = '\0';
85     }
86 #endif
87     pPath->append(buffer);
88 }
89
90 int processUserInput(int min, int max)
91 {
92     int input;
93
94     std::cin >> input;
95
96     if (!std::cin.fail() && min <= input && input <= max)
97         return input;
98
99     std::cin.clear();
100     std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
101     throw std::runtime_error("Invalid Input, please try again");
102 }
103
104 std::string processUserStringInput()
105 {
106     std::string input;
107
108     std::cin >> input;
109
110     return input;
111 }
112
113 void displayMenu()
114 {
115     std::cout << "================================================================" << std::endl;
116     std::cout << "          IoTivity Resource Container Test Application              " << std::endl;
117     std::cout << "================================================================" << std::endl;
118     std::cout << "   1.  Start Resource Container                                 " << std::endl;
119     std::cout << "   2.  Stop Resource Container                                  " << std::endl;
120     std::cout << "   3.  Add Sample Bundle                                        " << std::endl;
121     std::cout << "   4.  Start Sample Bundle                                      " << std::endl;
122     std::cout << "   5.  Stop Sample Bundle                                       " << std::endl;
123     std::cout << "   6.  Remove Sample Bundle                                     " << std::endl;
124     std::cout << "   7.  Add Sample Resource                                      " << std::endl;
125     std::cout << "   8.  Remove Sample Resource                                   " << std::endl;
126     std::cout << "   9.  List Bundles                                             " << std::endl;
127     std::cout << "   10. List Resources                                           " << std::endl;
128     std::cout << "   11. Exit                                                     " << std::endl;
129     std::cout << "================================================================" << std::endl;
130     std::cout << "   Please Enter the NO: ";
131 }
132
133 bool checkBundleRegistered(std::string bundleId)
134 {
135     std::list< std::unique_ptr< RCSBundleInfo > > bundleList;
136
137     if (g_bContainerStarted)
138     {
139         bundleList = g_pResourceContainer->listBundles();
140
141         for (auto &bundle : bundleList)
142         {
143             if (bundle->getID().compare(bundleId) == 0)
144                 return true;
145         }
146     }
147
148     std::cout << "Bundle \'" << bundleId << "\' is not registered." << std::endl;
149     return false;
150 }
151
152 bool checkResourceRegistered(std::string bundleId, std::string resourceUri)
153 {
154     std::list< std::string > resourceList;
155
156     if (g_bContainerStarted && checkBundleRegistered(bundleId))
157     {
158         resourceList = g_pResourceContainer->listBundleResources(bundleId);
159
160         for (auto &resource : resourceList)
161         {
162             if (resource.compare(resourceUri) == 0)
163                 return true;
164         }
165     }
166
167     std::cout << "Resource \'" << resourceUri << "\' is not registered." << std::endl;
168     return false;
169 }
170
171 void StartContainer(std::string configPath)
172 {
173     if (!g_bContainerStarted)
174     {
175         g_pResourceContainer->startContainer(configPath);
176         g_bContainerStarted = true;
177         std::cout << "Container started." << std::endl;
178     }
179     else
180     {
181         std::cout << "Container is already started." << std::endl;
182     }
183 }
184
185 void StopContainer()
186 {
187     if (g_pResourceContainer && g_bContainerStarted)
188     {
189         g_pResourceContainer->stopContainer();
190         g_bContainerStarted = false;
191     }
192     else
193     {
194         std::cout << "Container is not started." << std::endl;
195     }
196 }
197
198 void AddSampleBundle()
199 {
200     std::map< std::string, std::string > bundleParams;
201
202     if (g_pResourceContainer && g_bContainerStarted)
203     {
204         g_pResourceContainer->addBundle(EXAMPLE_BUNDLE_ID, EXAMPLE_BUNDLE_URI,
205                                         EXAMPLE_BUNDLE_PATH, EXAMPLE_BUNDLE_ACTIVATOR,
206                                         bundleParams);
207     }
208     else
209     {
210         std::cout << "Container is not started." << std::endl;
211     }
212 }
213
214 void StartSampleBundle()
215 {
216     if (g_pResourceContainer && g_bContainerStarted)
217     {
218         if (checkBundleRegistered(EXAMPLE_BUNDLE_ID))
219         {
220             g_pResourceContainer->startBundle(EXAMPLE_BUNDLE_ID);
221             g_bSampleBundleStarted = true;
222         }
223     }
224     else
225     {
226         std::cout << "Container is not started." << std::endl;
227     }
228 }
229
230 void StopSampleBundle()
231 {
232     if (g_pResourceContainer && g_bContainerStarted)
233     {
234         if (checkBundleRegistered(EXAMPLE_BUNDLE_ID) && g_bSampleBundleStarted)
235         {
236             g_pResourceContainer->stopBundle(EXAMPLE_BUNDLE_ID);
237             g_bSampleBundleStarted = false;
238         }
239         else
240             std::cout << "Sample Bundle is not started." << std::endl;
241     }
242     else
243     {
244         std::cout << "Container is not started." << std::endl;
245     }
246 }
247
248 void RemoveSampleBundle()
249 {
250     if (g_pResourceContainer && g_bContainerStarted)
251     {
252         if (checkBundleRegistered(EXAMPLE_BUNDLE_ID))
253             g_pResourceContainer->removeBundle(EXAMPLE_BUNDLE_ID);
254     }
255     else
256     {
257         std::cout << "Container is not started." << std::endl;
258     }
259 }
260
261 void AddSampleBundleResource()
262 {
263     std::map< std::string, std::string > resourceParams;
264
265     if (g_pResourceContainer && g_bContainerStarted)
266     {
267         if (checkBundleRegistered(EXAMPLE_BUNDLE_ID) && g_bSampleBundleStarted)
268         {
269             resourceParams.insert(std::make_pair("resourceType", EXAMPLE_RESOURCE_TYPE));
270             resourceParams.insert(std::make_pair("address", EXAMPLE_ADDRESS));
271
272             g_pResourceContainer->addResourceConfig(EXAMPLE_BUNDLE_ID, EXAMPLE_RESOURCE_URI,
273                                                     resourceParams);
274         }
275         else
276             std::cout << "Sample Bundle is not started." << std::endl;
277     }
278     else
279     {
280         std::cout << "Container is not started." << std::endl;
281     }
282 }
283
284 void RemoveSampleBundleResource()
285 {
286     if (g_pResourceContainer && g_bContainerStarted)
287     {
288         if (checkResourceRegistered(EXAMPLE_BUNDLE_ID, EXAMPLE_RESOURCE_URI)
289             && g_bSampleBundleStarted)
290             g_pResourceContainer->removeResourceConfig(EXAMPLE_BUNDLE_ID, EXAMPLE_RESOURCE_URI);
291         else
292             std::cout << "Sample Bundle is not started." << std::endl;
293     }
294     else
295     {
296         std::cout << "Container is not started." << std::endl;
297     }
298 }
299
300 void printBundleList(std::list< std::unique_ptr< RCSBundleInfo > > &list)
301 {
302     std::cout << std::endl;
303     for (auto &bundleinfo : list)
304     {
305         std::cout << "-- " << bundleinfo->getID() << std::endl;
306     }
307     std::cout << std::endl;
308 }
309
310 void ListBundles()
311 {
312     std::list< std::unique_ptr< RCSBundleInfo > > bundles;
313
314     if (g_pResourceContainer && g_bContainerStarted)
315     {
316         bundles = g_pResourceContainer->listBundles();
317         printBundleList(bundles);
318     }
319     else
320     {
321         std::cout << "Container is not started." << std::endl;
322     }
323 }
324
325 void printResourceList(std::list< std::string > &list)
326 {
327     std::cout << std::endl;
328     for (auto &bundleResource : list)
329     {
330         std::cout << "-- " << bundleResource << std::endl;
331     }
332     std::cout << std::endl;
333 }
334
335 void ListResources(std::string bundleId)
336 {
337     std::list< std::string > resources;
338
339     if (g_pResourceContainer && g_bContainerStarted)
340     {
341         if (checkBundleRegistered(bundleId))
342         {
343             resources = g_pResourceContainer->listBundleResources(bundleId);
344             printResourceList(resources);
345         }
346     }
347     else
348     {
349         std::cout << "Container is not started." << std::endl;
350     }
351 }
352
353 void ExecuteCommand(APPMenu menu)
354 {
355     switch (menu)
356     {
357         case APPMenu::START_RC:
358             {
359                 std::string filePath;
360                 std::cout << "Type Configuration File Path (Press \'0\' to start with example): ";
361
362                 if ((filePath = processUserStringInput()).compare("0") == 0)
363                 {
364                     getCurrentPath(&filePath);
365                     filePath.append(EXAMPLE_CONFIG_PATH);
366                 }
367
368                 StartContainer(filePath);
369             }
370             break;
371         case APPMenu::STOP_RC:
372             StopContainer();
373             break;
374         case APPMenu::ADD_SAMPLE_BUNDLE:
375             AddSampleBundle();
376             break;
377         case APPMenu::START_SAMPLE_BUNDLE:
378             StartSampleBundle();
379             break;
380         case APPMenu::STOP_SAMPLE_BUNDLE:
381             StopSampleBundle();
382             break;
383         case APPMenu::REMOVE_SAMPLE_BUNDLE:
384             RemoveSampleBundle();
385             break;
386         case APPMenu::ADD_SAMPLE_RESOURCE:
387             AddSampleBundleResource();
388             break;
389         case APPMenu::REMOVE_SAMPLE_RESOURCE:
390             RemoveSampleBundleResource();
391             break;
392         case APPMenu::LIST_BUNDLES:
393             ListBundles();
394             break;
395         case APPMenu::LIST_RESOURCES:
396             {
397                 std::string bundleId;
398                 std::cout <<
399                           "Type Bundle Id to get Resource List (Press \'0\' to get example resource list): ";
400
401                 if ((bundleId = processUserStringInput()).compare("0") == 0)
402                 {
403                     bundleId = EXAMPLE_BUNDLE_ID;
404                 }
405
406                 ListResources(bundleId);
407             }
408             break;
409         case APPMenu::EXIT:
410             throw CloseApp();
411             break;
412     }
413 }
414
415 int main()
416 {
417     g_pResourceContainer = RCSResourceContainer::getInstance();
418
419     while (true)
420     {
421         try
422         {
423             displayMenu();
424             ExecuteCommand((APPMenu)processUserInput(APPMenu::START_RC, APPMenu::EXIT));
425         }
426         catch (const std::exception &e)
427         {
428             std::cout << e.what() << std::endl;
429         }
430         catch (const CloseApp &)
431         {
432             break;
433         }
434     }
435
436     if (g_bContainerStarted)
437         g_pResourceContainer->stopContainer();
438
439     g_pResourceContainer = nullptr;
440
441     return 0;
442 }