resource-container: make registerResource() return status code
[platform/upstream/iotivity.git] / service / resource-container / src / ResourceContainerImpl.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 "ResourceContainerImpl.h"
22
23 #include <dlfcn.h>
24 #include <unistd.h>
25 #include <string.h>
26 #include <fstream>
27 #include <iostream>
28 #include <stdio.h>
29 #include <thread>
30 #include <mutex>
31 #include <algorithm>
32
33 #include "BundleActivator.h"
34 #include "SoftSensorResource.h"
35 #include "InternalTypes.h"
36
37 using namespace OIC::Service;
38 using namespace std;
39
40 namespace OIC
41 {
42     namespace Service
43     {
44         ResourceContainerImpl::ResourceContainerImpl()
45         {
46             m_config = nullptr;
47         }
48
49         ResourceContainerImpl::~ResourceContainerImpl()
50         {
51             m_config = nullptr;
52         }
53
54         bool has_suffix(const std::string &str, const std::string &suffix)
55         {
56             return str.size() >= suffix.size()
57                    && str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
58         }
59
60         void ResourceContainerImpl::startContainer(const std::string &configFile)
61         {
62             OC_LOG(INFO, CONTAINER_TAG, "Starting resource container.");
63 #if (JAVA_SUPPORT)
64             OC_LOG(INFO, CONTAINER_TAG, "Resource container has Java support.");
65 #else
66             OC_LOG(INFO, CONTAINER_TAG, "Resource container without Java support.");
67 #endif
68
69
70             activationLock.lock();
71             if (!configFile.empty())
72             {
73                 m_config = new Configuration(configFile);
74
75                 if (m_config->isLoaded())
76                 {
77                     configInfo bundles;
78                     m_config->getConfiguredBundles(&bundles);
79
80                     for (unsigned int i = 0; i < bundles.size(); i++)
81                     {
82                         BundleInfoInternal *bundleInfo = new BundleInfoInternal();
83                         bundleInfo->setPath(bundles[i][BUNDLE_PATH]);
84                         bundleInfo->setVersion(bundles[i][BUNDLE_VERSION]);
85                         bundleInfo->setID(bundles[i][BUNDLE_ID]);
86                         if (!bundles[i][BUNDLE_ACTIVATOR].empty())
87                         {
88                             string activatorName = bundles[i][BUNDLE_ACTIVATOR];
89                             std::replace(activatorName.begin(), activatorName.end(), '.', '/');
90                             ((BundleInfoInternal *) bundleInfo)->setActivatorName(activatorName);
91                             ((BundleInfoInternal *) bundleInfo)->setLibraryPath(
92                                 bundles[i][BUNDLE_LIBRARY_PATH]);
93                         }
94
95                         OC_LOG_V(INFO, CONTAINER_TAG, "Init Bundle:(%s)",
96                                  std::string(bundles[i][BUNDLE_ID] + ";" +
97                                              bundles[i][BUNDLE_PATH]).c_str());
98
99                         registerBundle(bundleInfo);
100                         activateBundle(bundleInfo);
101                     }
102                 }
103                 else
104                 {
105                     OC_LOG_V(ERROR, CONTAINER_TAG, "Container started with invalid configfile path.");
106                 }
107             }
108             else
109             {
110                 OC_LOG_V(INFO, CONTAINER_TAG, "No configuration file for the container provided.");
111             }
112
113             map<std::string, boost::thread >::iterator activatorIterator;
114
115             for (activatorIterator = m_activators.begin(); activatorIterator != m_activators.end();
116                  activatorIterator++)
117             {
118                 activatorIterator->second.timed_join(
119                     boost::posix_time::seconds(BUNDLE_ACTIVATION_WAIT_SEC));
120                 // wait for bundles to be activated
121             }
122             activationLock.unlock();
123         }
124
125         void ResourceContainerImpl::stopContainer()
126         {
127             OC_LOG(INFO, CONTAINER_TAG, "Stopping resource container.");
128
129             for (std::map< std::string, BundleInfoInternal * >::iterator it = m_bundles.begin();
130                  it != m_bundles.end(); ++it)
131             {
132                 BundleInfoInternal *bundleInfo = it->second;
133                 deactivateBundle(bundleInfo);
134                 unregisterBundle(bundleInfo);
135             }
136
137             if (!m_mapServers.empty())
138             {
139                 map< std::string, RCSResourceObject::Ptr >::iterator itor = m_mapServers.begin();
140
141                 while (itor != m_mapServers.end())
142                 {
143                     (itor++)->second.reset();
144                 }
145
146                 m_mapResources.clear();
147                 m_mapBundleResources.clear();
148             }
149
150             if (m_config)
151                 delete m_config;
152         }
153
154         void ResourceContainerImpl::activateBundle(RCSBundleInfo *bundleInfo)
155         {
156             activationLock.lock();
157             BundleInfoInternal *bundleInfoInternal = (BundleInfoInternal *) bundleInfo;
158
159             if (bundleInfoInternal->isLoaded())
160             {
161                 activateBundle(bundleInfo->getID());
162             }
163             activationLock.unlock();
164         }
165
166         void ResourceContainerImpl::deactivateBundle(RCSBundleInfo *bundleInfo)
167         {
168             if (((BundleInfoInternal *) bundleInfo)->isActivated())
169             {
170                 deactivateBundle(bundleInfo->getID());
171             }
172         }
173
174         void ResourceContainerImpl::activateBundle(const std::string &id)
175         {
176             OC_LOG_V(INFO, CONTAINER_TAG, "Activating bundle: (%s)",
177                      std::string(m_bundles[id]->getID()).c_str());
178             activationLock.lock();
179             auto f = std::bind(&ResourceContainerImpl::activateBundleThread, this,
180                                id);
181             boost::thread activator(f);
182             activator.timed_join(boost::posix_time::seconds(BUNDLE_SET_GET_WAIT_SEC));
183             activationLock.unlock();
184             OC_LOG_V(INFO, CONTAINER_TAG, "Bundle activated: (%s)",
185                      std::string(m_bundles[id]->getID()).c_str());
186         }
187
188         void ResourceContainerImpl::deactivateBundle(const std::string &id)
189         {
190             if (m_bundles[id]->getJavaBundle())
191             {
192 #if(JAVA_SUPPORT)
193                 deactivateJavaBundle(id);
194 #endif
195             }
196             else
197             {
198                 deactivateSoBundle(id);
199             }
200         }
201
202         // loads the bundle
203         void ResourceContainerImpl::registerBundle(RCSBundleInfo *bundleInfo)
204         {
205             OC_LOG_V(INFO, CONTAINER_TAG, "Registering bundle: (%s)",
206                      std::string(bundleInfo->getPath()).c_str());
207
208             if (has_suffix(bundleInfo->getPath(), ".jar"))
209             {
210 #if(JAVA_SUPPORT)
211                 ((BundleInfoInternal *) bundleInfo)->setJavaBundle(true);
212                 registerJavaBundle(bundleInfo);
213 #endif
214             }
215             else
216             {
217                 ((BundleInfoInternal *) bundleInfo)->setJavaBundle(false);
218                 registerSoBundle(bundleInfo);
219             }
220         }
221
222         void ResourceContainerImpl::unregisterBundle(RCSBundleInfo *bundleInfo)
223         {
224             BundleInfoInternal *bundleInfoInternal = (BundleInfoInternal *) bundleInfo;
225             if (bundleInfoInternal->isLoaded() && !bundleInfoInternal->isActivated())
226             {
227                 if (!bundleInfoInternal->getJavaBundle())
228                 {
229                     unregisterBundleSo(bundleInfo->getID());
230                 }
231                 else
232                 {
233 #if(JAVA_SUPPORT)
234                     unregisterBundleJava(bundleInfo->getID());
235 #endif
236                 }
237             }
238         }
239
240         void ResourceContainerImpl::unregisterBundleSo(const std::string &id)
241         {
242             void *bundleHandle = m_bundles[id]->getBundleHandle();
243
244             OC_LOG_V(INFO, CONTAINER_TAG, "Unregister bundle: (%s)",
245                      std::string(m_bundles[id]->getID()).c_str());
246
247             const char *error;
248             dlclose(bundleHandle);
249
250             if ((error = dlerror()) != NULL)
251             {
252                 OC_LOG_V(ERROR, CONTAINER_TAG, "Error (%s)", error);
253             }
254             else
255             {
256                 delete m_bundles[id];
257                 m_bundles.erase(id);
258             }
259         }
260
261         int ResourceContainerImpl::registerResource(BundleResource::Ptr resource)
262         {
263             string strUri = resource->m_uri;
264             string strResourceType = resource->m_resourceType;
265             RCSResourceObject::Ptr server = nullptr;
266             int ret = EINVAL;
267
268             OC_LOG_V(INFO, CONTAINER_TAG, "Registration of resource (%s)" ,
269                      std::string(strUri + ", " + strResourceType).c_str());
270
271             registrationLock.lock();
272             if (m_mapResources.find(strUri) == m_mapResources.end())
273             {
274                 server = buildResourceObject(strUri, strResourceType);
275
276                 if (server != nullptr)
277                 {
278                     m_mapServers[strUri] = server;
279                     m_mapResources[strUri] = resource;
280                     m_mapBundleResources[resource->m_bundleId].push_back(strUri);
281
282                     server->setGetRequestHandler(
283                         std::bind(&ResourceContainerImpl::getRequestHandler, this,
284                                   std::placeholders::_1, std::placeholders::_2));
285
286                     server->setSetRequestHandler(
287                         std::bind(&ResourceContainerImpl::setRequestHandler, this,
288                                   std::placeholders::_1, std::placeholders::_2));
289
290                     OC_LOG_V(INFO, CONTAINER_TAG, "Registration finished (%s)",
291                              std::string(strUri + ", " +
292                                          strResourceType).c_str());
293
294                     if (m_config->isHasInput(resource->m_bundleId))
295                     {
296                         discoverInputResource(strUri);
297                     }
298
299                     // to get notified if bundle resource attributes are updated
300                     resource->registerObserver((NotificationReceiver *) this);
301                     ret = 0;
302                 }
303             }
304             else
305             {
306                 OC_LOG_V(ERROR, CONTAINER_TAG, "resource with (%s)",
307                          std::string(strUri + " already exists.").c_str());
308                 ret = -EEXIST;
309             }
310             registrationLock.unlock();
311
312             return ret;
313         }
314
315         void ResourceContainerImpl::unregisterResource(BundleResource::Ptr resource)
316         {
317             string strUri = resource->m_uri;
318             string strResourceType = resource->m_resourceType;
319
320             OC_LOG_V(INFO, CONTAINER_TAG, "Unregistration of resource (%s)",
321                      std::string(resource->m_uri + ", " +
322                                  resource->m_resourceType).c_str());
323
324             if (m_config->isHasInput(resource->m_bundleId))
325             {
326                 undiscoverInputResource(strUri);
327             }
328
329             if (m_mapServers.find(strUri) != m_mapServers.end())
330             {
331                 m_mapServers[strUri].reset();
332
333                 m_mapResources.erase(m_mapResources.find(strUri));
334                 m_mapBundleResources[resource->m_bundleId].remove(strUri);
335             }
336         }
337
338         void ResourceContainerImpl::getBundleConfiguration(const std::string &bundleId,
339                 configInfo *configOutput)
340         {
341             if (m_config)
342             {
343                 m_config->getBundleConfiguration(bundleId, (configInfo *) configOutput);
344             }
345         }
346
347         void ResourceContainerImpl::getResourceConfiguration(const std::string &bundleId,
348                 std::vector< resourceInfo > *configOutput)
349         {
350             if (m_config)
351             {
352                 m_config->getResourceConfiguration(bundleId, configOutput);
353             }
354         }
355
356         RCSGetResponse ResourceContainerImpl::getRequestHandler(const RCSRequest &request,
357                 const RCSResourceAttributes &)
358         {
359             RCSResourceAttributes attr;
360             std::string strResourceUri = request.getResourceUri();
361
362             if (m_mapServers.find(strResourceUri) != m_mapServers.end()
363                 && m_mapResources.find(strResourceUri) != m_mapResources.end())
364             {
365                 if (m_mapResources[strResourceUri])
366                 {
367                     auto getFunction = [this, &attr, &strResourceUri]()
368                     {
369                         attr = m_mapResources[strResourceUri]->handleGetAttributesRequest();
370                     };
371                     boost::thread getThread(getFunction);
372                     getThread.timed_join(boost::posix_time::seconds(BUNDLE_SET_GET_WAIT_SEC));
373
374                 }
375             }
376
377             return RCSGetResponse::create(std::move(attr), 200);
378         }
379
380         RCSSetResponse ResourceContainerImpl::setRequestHandler(const RCSRequest &request,
381                 const RCSResourceAttributes &attributes)
382         {
383             RCSResourceAttributes attr;
384             std::list<std::string> lstAttributes;
385             std::string strResourceUri = request.getResourceUri();
386
387             if (m_mapServers.find(strResourceUri) != m_mapServers.end()
388                 && m_mapResources.find(strResourceUri) != m_mapResources.end())
389             {
390                 if (m_mapResources[strResourceUri])
391                 {
392                     auto setFunction = [this, &lstAttributes, &strResourceUri, &attributes, &attr]()
393                     {
394                         lstAttributes = m_mapResources[strResourceUri]->getAttributeNames();
395
396                         for (RCSResourceAttributes::const_iterator itor = attributes.begin();
397                              itor != attributes.end(); itor++)
398                         {
399                             if (std::find(lstAttributes.begin(), lstAttributes.end(), itor->key())
400                                 != lstAttributes.end())
401                             {
402                                 attr[itor->key()] = itor->value();
403                             }
404                         }
405
406                         m_mapResources[strResourceUri]->handleSetAttributesRequest(attr);
407                     };
408                     boost::thread setThread(setFunction);
409                     setThread.timed_join(boost::posix_time::seconds(BUNDLE_SET_GET_WAIT_SEC));
410                 }
411             }
412
413             return RCSSetResponse::create(std::move(attr), 200);
414         }
415
416         void ResourceContainerImpl::onNotificationReceived(const std::string &strResourceUri)
417         {
418             OC_LOG_V(INFO, CONTAINER_TAG,
419                      "notification from (%s)", std::string(strResourceUri + ".").c_str());
420
421             if (m_mapServers.find(strResourceUri) != m_mapServers.end())
422             {
423                 m_mapServers[strResourceUri]->notify();
424             }
425         }
426
427         ResourceContainerImpl *ResourceContainerImpl::getImplInstance()
428         {
429             static ResourceContainerImpl m_instance;
430             return &m_instance;
431         }
432
433         RCSResourceObject::Ptr ResourceContainerImpl::buildResourceObject(const std::string &strUri,
434                 const std::string &strResourceType)
435         {
436             return RCSResourceObject::Builder(strUri, strResourceType,
437                                               "oic.if.baseline").setObservable(
438                        true).setDiscoverable(true).build();
439         }
440
441         void ResourceContainerImpl::startBundle(const std::string &bundleId)
442         {
443             if (m_bundles.find(bundleId) != m_bundles.end())
444             {
445                 if (!m_bundles[bundleId]->isActivated())
446                     activateBundle(m_bundles[bundleId]);
447                 else
448                 {
449                     OC_LOG(ERROR, CONTAINER_TAG, "Bundle already started");
450                 }
451             }
452             else
453             {
454                 OC_LOG_V(ERROR, CONTAINER_TAG, "Bundle with ID \'(%s)",
455                          std::string(bundleId + "\' is not registered.").c_str());
456             }
457         }
458
459         void ResourceContainerImpl::stopBundle(const std::string &bundleId)
460         {
461             if (m_bundles.find(bundleId) != m_bundles.end())
462             {
463                 if (m_bundles[bundleId]->isActivated())
464                     deactivateBundle(m_bundles[bundleId]);
465                 else
466                 {
467                     OC_LOG(ERROR, CONTAINER_TAG, "Bundle not activated");
468                 }
469             }
470             else
471             {
472                 OC_LOG_V(ERROR, CONTAINER_TAG, "Bundle with ID \'(%s)",
473                          std::string(bundleId + "\' is not registered.").c_str());
474             }
475         }
476
477         void ResourceContainerImpl::addBundle(const std::string &bundleId,
478                                               const std::string &bundleUri, const std::string &bundlePath,
479                                               const std::string &activator, std::map< string, string > params)
480         {
481             (void) bundleUri;
482
483             if (m_bundles.find(bundleId) != m_bundles.end())
484                 OC_LOG(ERROR, CONTAINER_TAG, "BundleId already exist");
485
486             else
487             {
488                 BundleInfoInternal *bundleInfo = new BundleInfoInternal();
489                 bundleInfo->setID(bundleId);
490                 bundleInfo->setPath(bundlePath);
491                 bundleInfo->setActivatorName(activator);
492                 if (params.find("libraryPath") != params.end())
493                 {
494                     string activatorName = activator; // modify activator for Java bundle
495                     std::replace(activatorName.begin(), activatorName.end(), '.', '/');
496                     ((BundleInfoInternal *) bundleInfo)->setActivatorName(activatorName);
497                     ((BundleInfoInternal *)bundleInfo)->setLibraryPath(params[BUNDLE_LIBRARY_PATH]);
498                 }
499
500                 OC_LOG_V(INFO, CONTAINER_TAG, "Add Bundle: (%s)",
501                          std::string(bundleInfo->getID() + "; " +
502                                      bundleInfo->getPath()).c_str());
503
504                 registerBundle(bundleInfo);
505             }
506         }
507
508         void ResourceContainerImpl::removeBundle(const std::string &bundleId)
509         {
510             if (m_bundles.find(bundleId) != m_bundles.end())
511             {
512                 BundleInfoInternal *bundleInfo = m_bundles[bundleId];
513                 if (bundleInfo->isActivated())
514                     deactivateBundle(bundleInfo);
515
516                 if (bundleInfo->isLoaded())
517                     unregisterBundle(bundleInfo);
518             }
519             else
520             {
521                 OC_LOG_V(ERROR, CONTAINER_TAG, "Bundle with ID \'(%s)",
522                          std::string(bundleId + "\' is not registered.").c_str());
523             }
524         }
525
526         std::list<std::unique_ptr<RCSBundleInfo>> ResourceContainerImpl::listBundles()
527         {
528             std::list<std::unique_ptr<RCSBundleInfo> > ret;
529             for (std::map< std::string, BundleInfoInternal * >::iterator it = m_bundles.begin();
530                  it != m_bundles.end(); ++it)
531             {
532                 {
533                     std::unique_ptr<BundleInfoInternal> bundleInfo(new BundleInfoInternal);
534                     (bundleInfo)->setBundleInfo(it->second);
535                     ret.push_back(std::move(bundleInfo));
536                 }
537             }
538             return ret;
539         }
540
541         void ResourceContainerImpl::addResourceConfig(const std::string &bundleId,
542                 const std::string &resourceUri, std::map< string, string > params)
543         {
544             if (m_bundles.find(bundleId) != m_bundles.end())
545             {
546                 if (!m_bundles[bundleId]->getJavaBundle())
547                 {
548                     resourceInfo newResourceInfo;
549                     newResourceInfo.uri = resourceUri;
550
551                     if (params.find(OUTPUT_RESOURCE_NAME) != params.end())
552                         newResourceInfo.name = params[OUTPUT_RESOURCE_NAME];
553                     if (params.find(OUTPUT_RESOURCE_TYPE) != params.end())
554                         newResourceInfo.resourceType = params[OUTPUT_RESOURCE_TYPE];
555                     if (params.find(OUTPUT_RESOURCE_ADDR) != params.end())
556                         newResourceInfo.address = params[OUTPUT_RESOURCE_ADDR];
557
558                     addSoBundleResource(bundleId, newResourceInfo);
559                 }
560             }
561             else
562             {
563                 OC_LOG_V(ERROR, CONTAINER_TAG, "Bundle with ID \'(%s)",
564                          std::string(bundleId + "\' is not registered.").c_str());
565             }
566         }
567
568         void ResourceContainerImpl::removeResourceConfig(const std::string &bundleId,
569                 const std::string &resourceUri)
570         {
571             if (m_bundles.find(bundleId) != m_bundles.end())
572             {
573                 if (!m_bundles[bundleId]->getJavaBundle())
574                 {
575                     removeSoBundleResource(bundleId, resourceUri);
576                 }
577             }
578             else
579             {
580                 OC_LOG_V(ERROR, CONTAINER_TAG, "Bundle with ID \'(%s)",
581                          std::string(bundleId + "\' is not registered.").c_str());
582             }
583         }
584
585         std::list< string > ResourceContainerImpl::listBundleResources(const std::string &bundleId)
586         {
587             std::list < string > ret;
588
589             if (m_mapBundleResources.find(bundleId) != m_mapBundleResources.end())
590             {
591                 ret = m_mapBundleResources[bundleId];
592             }
593
594             return ret;
595
596         }
597
598         void ResourceContainerImpl::registerSoBundle(RCSBundleInfo *bundleInfo)
599         {
600             const char *error;
601
602             activator_t *bundleActivator = NULL;
603             deactivator_t *bundleDeactivator = NULL;
604             resourceCreator_t *resourceCreator = NULL;
605             resourceDestroyer_t *resourceDestroyer = NULL;
606             BundleInfoInternal *bundleInfoInternal = (BundleInfoInternal *) bundleInfo;
607             void *bundleHandle = NULL;
608             bundleHandle = dlopen(bundleInfo->getPath().c_str(), RTLD_LAZY);
609
610             if (bundleHandle != NULL)
611             {
612                 bundleActivator =
613                     (activator_t *) dlsym(bundleHandle,
614                                           ("" + bundleInfoInternal->getActivatorName()
615                                            + "_externalActivateBundle").c_str());
616                 bundleDeactivator =
617                     (deactivator_t *) dlsym(bundleHandle,
618                                             ("" + bundleInfoInternal->getActivatorName()
619                                              + "_externalDeactivateBundle").c_str());
620                 resourceCreator =
621                     (resourceCreator_t *) dlsym(bundleHandle,
622                                                 ("" + bundleInfoInternal->getActivatorName()
623                                                  + "_externalCreateResource").c_str());
624                 resourceDestroyer =
625                     (resourceDestroyer_t *) dlsym(bundleHandle,
626                                                   ("" + bundleInfoInternal->getActivatorName()
627                                                    + "_externalDestroyResource").c_str());
628
629
630                 if ((error = dlerror()) != NULL)
631                 {
632                     OC_LOG_V(ERROR, CONTAINER_TAG, "Error : (%s)", error);
633                 }
634                 else
635                 {
636                     ((BundleInfoInternal *) bundleInfo)->setBundleActivator(bundleActivator);
637                     ((BundleInfoInternal *) bundleInfo)->setBundleDeactivator(bundleDeactivator);
638                     ((BundleInfoInternal *) bundleInfo)->setResourceCreator(resourceCreator);
639                     ((BundleInfoInternal *) bundleInfo)->setResourceDestroyer(resourceDestroyer);
640                     ((BundleInfoInternal *) bundleInfo)->setLoaded(true);
641                     ((BundleInfoInternal *) bundleInfo)->setBundleHandle(bundleHandle);
642
643                     m_bundles[bundleInfo->getID()] = ((BundleInfoInternal *) bundleInfo);
644                 }
645             }
646             else
647             {
648                 if ((error = dlerror()) != NULL)
649                 {
650                     OC_LOG_V(ERROR, CONTAINER_TAG, "Error : (%s)", error);
651                 }
652             }
653         }
654
655         void ResourceContainerImpl::activateSoBundle(const std::string &bundleId)
656         {
657             activator_t *bundleActivator = m_bundles[bundleId]->getBundleActivator();
658
659             if (bundleActivator != NULL)
660             {
661                 bundleActivator(this, m_bundles[bundleId]->getID());
662                 m_bundles[bundleId]->setActivated(true);
663             }
664             else
665             {
666                 //Unload module and return error
667                 OC_LOG(ERROR, CONTAINER_TAG, "Activation unsuccessful.");
668             }
669
670             BundleInfoInternal *bundleInfoInternal = (BundleInfoInternal *) m_bundles[bundleId];
671             bundleInfoInternal->setActivated(true);
672
673         }
674
675         void ResourceContainerImpl::undiscoverInputResource(const std::string &outputResourceUri)
676         {
677             auto foundDiscoverResource = m_mapDiscoverResourceUnits.find(outputResourceUri);
678             if (foundDiscoverResource != m_mapDiscoverResourceUnits.end())
679             {
680                 m_mapDiscoverResourceUnits.erase(foundDiscoverResource);
681             }
682         }
683
684         void ResourceContainerImpl::discoverInputResource(const std::string &outputResourceUri)
685         {
686             auto foundOutputResource = m_mapResources.find(outputResourceUri);
687             auto resourceProperty = foundOutputResource->second->m_mapResourceProperty;
688
689             try
690             {
691                 resourceProperty.at(INPUT_RESOURCE);
692             }
693             catch (std::out_of_range &e)
694             {
695                 return;
696             }
697
698             for (auto iter : resourceProperty)
699             {
700                 if (iter.first.compare(INPUT_RESOURCE) == 0)
701                 {
702                     for (auto it : iter.second)
703                     {
704                         auto makeValue = [&](const std::string & reference) mutable -> std::string
705                         {
706                             std::string retStr = "";
707                             try
708                             {
709                                 retStr = it.at(reference);
710                             }
711                             catch (std::out_of_range &e)
712                             {
713                                 return "";
714                             }
715                             return retStr;
716                         };
717                         std::string uri = makeValue(INPUT_RESOURCE_URI);
718                         std::string type = makeValue(INPUT_RESOURCE_TYPE);
719                         std::string attributeName = makeValue(INPUT_RESOURCE_ATTRIBUTENAME);
720
721                         DiscoverResourceUnit::Ptr newDiscoverUnit = std::make_shared
722                                 < DiscoverResourceUnit > (outputResourceUri);
723                         newDiscoverUnit->startDiscover(
724                             DiscoverResourceUnit::DiscoverResourceInfo(uri, type,
725                                     attributeName),
726                             std::bind(&SoftSensorResource::onUpdatedInputResource,
727                                       std::static_pointer_cast< SoftSensorResource > (foundOutputResource->second),
728                                       std::placeholders::_1, std::placeholders::_2));
729
730                         auto foundDiscoverResource = m_mapDiscoverResourceUnits.find(
731                                                          outputResourceUri);
732                         if (foundDiscoverResource != m_mapDiscoverResourceUnits.end())
733                         {
734                             foundDiscoverResource->second.push_back(newDiscoverUnit);
735                         }
736                         else
737                         {
738                             m_mapDiscoverResourceUnits.insert(
739                                 std::make_pair(outputResourceUri,
740                                                std::list< DiscoverResourceUnit::Ptr >
741                             { newDiscoverUnit }));
742                         }
743                     }
744                 }
745             }
746         }
747
748         void ResourceContainerImpl::deactivateSoBundle(const std::string &id)
749         {
750             deactivator_t *bundleDeactivator = m_bundles[id]->getBundleDeactivator();
751
752             OC_LOG_V(INFO, CONTAINER_TAG, "De-activating bundle: (%s)", std::string(
753                          m_bundles[id]->getID()).c_str());
754
755             if (bundleDeactivator != NULL)
756             {
757                 bundleDeactivator();
758                 m_bundles[id]->setActivated(false);
759             }
760             else
761             {
762                 //Unload module and return error
763                 OC_LOG(ERROR, CONTAINER_TAG, "De-activation unsuccessful.");
764             }
765         }
766
767         void ResourceContainerImpl::addSoBundleResource(const std::string &bundleId,
768                 resourceInfo newResourceInfo)
769         {
770             resourceCreator_t *resourceCreator;
771
772             resourceCreator = m_bundles[bundleId]->getResourceCreator();
773
774             if (resourceCreator != NULL)
775             {
776                 resourceCreator(newResourceInfo);
777             }
778             else
779             {
780                 OC_LOG(ERROR, CONTAINER_TAG, "addResource unsuccessful.");
781             }
782         }
783
784         void ResourceContainerImpl::removeSoBundleResource(const std::string &bundleId,
785                 const std::string &resourceUri)
786         {
787             if (m_mapResources.find(resourceUri) != m_mapResources.end())
788             {
789                 resourceDestroyer_t *resourceDestroyer =
790                     m_bundles[bundleId]->getResourceDestroyer();
791
792                 if (resourceDestroyer != NULL)
793                 {
794                     resourceDestroyer(m_mapResources[resourceUri]);
795                 }
796                 else
797                 {
798                     OC_LOG(ERROR, CONTAINER_TAG, "removeResource unsuccessful.");
799                 }
800             }
801         }
802
803         void ResourceContainerImpl::activateBundleThread(const std::string &id)
804         {
805             OC_LOG_V(INFO, CONTAINER_TAG, "Activating bundle: (%s)",
806                      std::string(m_bundles[id]->getID()).c_str());
807
808             if (m_bundles[id]->getJavaBundle())
809             {
810 #if(JAVA_SUPPORT)
811                 activateJavaBundle(id);
812 #endif
813             }
814             else
815             {
816                 activateSoBundle (id);
817             }
818
819             OC_LOG_V(INFO, CONTAINER_TAG, "Bundle activated: (%s)",
820                      std::string(m_bundles[id]->getID()).c_str());
821         }
822
823 #if(JAVA_SUPPORT)
824         JavaVM *ResourceContainerImpl::getJavaVM(string bundleId)
825         {
826             return m_bundleVM[bundleId];
827         }
828
829         void ResourceContainerImpl::registerJavaBundle(RCSBundleInfo *bundleInfo)
830         {
831             OC_LOG_V(INFO, CONTAINER_TAG, "Registering Java bundle (%s)",
832                      std::string(bundleInfo->getID()).c_str());
833             JavaVM *jvm;
834             JNIEnv *env;
835             JavaVMInitArgs vm_args;
836             JavaVMOption options[3];
837
838             BundleInfoInternal *bundleInfoInternal = (BundleInfoInternal *) bundleInfo;
839
840             if (FILE *file = fopen(bundleInfo->getPath().c_str(), "r"))
841             {
842                 fclose(file);
843
844                 OC_LOG_V(INFO, CONTAINER_TAG, "Resource bundle (%s)",
845                          std::string(bundleInfo->getPath() +
846                                      " available.").c_str());
847             }
848             else
849             {
850                 OC_LOG_V(ERROR, CONTAINER_TAG, "Resource bundle (%s)",
851                          std::string(bundleInfo->getPath() + " not available.").c_str());
852
853                 return;
854             }
855
856             char optionString[] = "-Djava.compiler=NONE";
857             options[0].optionString = optionString;
858             char classpath[1000];
859             strcpy(classpath, "-Djava.class.path=");
860             strcat(classpath, bundleInfo->getPath().c_str());
861
862             OC_LOG(INFO, CONTAINER_TAG,
863                    std::string("Configured classpath: ").append(classpath).c_str());
864
865             options[1].optionString = classpath;
866
867             char libraryPath[1000];
868             strcpy(libraryPath, "-Djava.library.path=");
869             strcat(libraryPath, bundleInfo->getLibraryPath().c_str());
870             options[2].optionString = libraryPath;
871
872             OC_LOG(INFO, CONTAINER_TAG,
873                    std::string("Configured library path: ").append(libraryPath).c_str());
874
875             vm_args.version = JNI_VERSION_1_4;
876             vm_args.options = options;
877             vm_args.nOptions = 3;
878             vm_args.ignoreUnrecognized = 1;
879
880             int res;
881             res = JNI_CreateJavaVM(&jvm, (void **) &env, &vm_args);
882
883             if (res < 0)
884             {
885                 OC_LOG(ERROR, CONTAINER_TAG, "cannot create JavaVM.");
886                 return;
887             }
888             else
889             {
890                 OC_LOG(INFO, CONTAINER_TAG, "JVM successfully created.");
891             }
892
893             m_bundleVM.insert(std::pair< string, JavaVM * >(bundleInfo->getID(), jvm));
894
895             const char *className = bundleInfoInternal->getActivatorName().c_str();
896
897             OC_LOG_V(INFO, CONTAINER_TAG, "Looking up class: (%s)", std::string(
898                          bundleInfoInternal->getActivatorName() + "|").c_str());
899
900             jclass bundleActivatorClass = env->FindClass(className);
901
902             if (bundleActivatorClass == NULL)
903             {
904                 OC_LOG_V(ERROR, CONTAINER_TAG, "Cannot register bundle (%s)",
905                          std::string( bundleInfoInternal->getID()
906                                       + " bundle activator(" + bundleInfoInternal->getActivatorName()
907                                       + ") not found ").c_str());
908                 return;
909             }
910
911             jmethodID activateMethod = env->GetMethodID(bundleActivatorClass, "activateBundle",
912                                        "()V");
913
914             if (activateMethod == NULL)
915             {
916                 OC_LOG_V(ERROR, CONTAINER_TAG, "Cannot register bundle (%s)",
917                          std::string( bundleInfoInternal->getID()
918                                       + " activate bundle method not found ").c_str());
919                 return;
920             }
921             bundleInfoInternal->setJavaBundleActivatorMethod(activateMethod);
922
923             jmethodID deactivateMethod = env->GetMethodID(bundleActivatorClass, "deactivateBundle",
924                                          "()V");
925
926             if (deactivateMethod == NULL)
927             {
928                 OC_LOG_V(ERROR, CONTAINER_TAG, "Cannot register bundle (%s)",
929                          std::string( bundleInfoInternal->getID()
930                                       + " deactivate bundle method not found ").c_str());
931                 return;
932             }
933
934             bundleInfoInternal->setJavaBundleDeactivatorMethod(deactivateMethod);
935
936             jmethodID constructor;
937
938             constructor = env->GetMethodID(bundleActivatorClass, "<init>", "(Ljava/lang/String;)V");
939
940             jstring bundleID = env->NewStringUTF(bundleInfoInternal->getID().c_str());
941
942             jobject bundleActivator = env->NewObject(bundleActivatorClass, constructor, bundleID);
943
944             bundleInfoInternal->setJavaBundleActivatorObject(bundleActivator);
945
946             bundleInfoInternal->setLoaded(true);
947
948             m_bundles[bundleInfo->getID()] = ((BundleInfoInternal *)bundleInfo);
949
950
951             OC_LOG(INFO, CONTAINER_TAG, "Bundle registered");
952         }
953
954         void ResourceContainerImpl::activateJavaBundle(string bundleId)
955         {
956             OC_LOG(INFO, CONTAINER_TAG, "Activating java bundle");
957
958             JavaVM *vm = getJavaVM(bundleId);
959             BundleInfoInternal *bundleInfoInternal = (BundleInfoInternal *) m_bundles[bundleId];
960             JNIEnv *env;
961             int envStat = vm->GetEnv((void **) &env, JNI_VERSION_1_4);
962
963             if (envStat == JNI_EDETACHED)
964             {
965                 if (vm->AttachCurrentThread((void **) &env, NULL) != 0)
966                 {
967                     OC_LOG(ERROR, CONTAINER_TAG, "Failed to attach ");
968                 }
969             }
970             else if (envStat == JNI_EVERSION)
971             {
972                 OC_LOG(ERROR, CONTAINER_TAG, "Env: version not supported ");
973             }
974
975             env->CallVoidMethod(bundleInfoInternal->getJavaBundleActivatorObject(),
976                                 bundleInfoInternal->getJavaBundleActivatorMethod());
977
978             m_bundles[bundleId]->setActivated(true);
979         }
980
981         void ResourceContainerImpl::deactivateJavaBundle(string bundleId)
982         {
983             OC_LOG(INFO, CONTAINER_TAG, "Deactivating java bundle");
984
985             JavaVM *vm = getJavaVM(bundleId);
986             BundleInfoInternal *bundleInfoInternal = (BundleInfoInternal *) m_bundles[bundleId];
987             JNIEnv *env;
988             int envStat = vm->GetEnv((void **) &env, JNI_VERSION_1_4);
989
990             if (envStat == JNI_EDETACHED)
991             {
992                 if (vm->AttachCurrentThread((void **) &env, NULL) != 0)
993                 {
994                     OC_LOG(ERROR, CONTAINER_TAG, "Failed to attach ");
995                 }
996             }
997             else if (envStat == JNI_EVERSION)
998             {
999                 OC_LOG(ERROR, CONTAINER_TAG, "Env: version not supported ");
1000             }
1001
1002             env->CallVoidMethod(bundleInfoInternal->getJavaBundleActivatorObject(),
1003                                 bundleInfoInternal->getJavaBundleDeactivatorMethod());
1004
1005             m_bundles[bundleId]->setActivated(false);
1006         }
1007
1008         void ResourceContainerImpl::unregisterBundleJava(string id)
1009         {
1010             OC_LOG_V(INFO, CONTAINER_TAG, "Unregister Java bundle: (%s)", std::string(
1011                          m_bundles[id]->getID()).c_str());
1012
1013             OC_LOG(INFO, CONTAINER_TAG, "Destroying JVM");
1014
1015             m_bundleVM[id]->DestroyJavaVM();
1016
1017             delete m_bundles[id];
1018             m_bundles.erase(id);
1019         }
1020 #endif
1021     }
1022 }