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