Imported Upstream version 1.0.1
[platform/upstream/iotivity.git] / service / simulator / src / service-provider / resource_manager.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 "resource_manager.h"
22 #include "simulator_logger.h"
23 #include "logger.h"
24
25 #define TAG "RESOURCE_MANAGER"
26
27 ResourceManager *ResourceManager::getInstance()
28 {
29     static ResourceManager s_instance;
30     return &s_instance;
31 }
32
33 SimulatorResourceServerSP ResourceManager::createResource(const std::string &configPath,
34         SimulatorResourceServer::ResourceModelChangedCB callback)
35 {
36     OC_LOG_V(INFO, "Create resource request : config=%s", configPath.c_str());
37
38     // Input validation
39     if (configPath.empty())
40     {
41         OC_LOG(ERROR, TAG, "Invalid config file path!");
42         throw InvalidArgsException(SIMULATOR_INVALID_PARAM, "Invalid RAML file path!");
43     }
44
45     if (!callback)
46     {
47         OC_LOG(ERROR, TAG, "Invalid callback!");
48         throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid callback!");
49     }
50
51     return buildResource(configPath, callback);
52 }
53
54 std::vector<SimulatorResourceServerSP> ResourceManager::createResource(
55     const std::string &configPath, unsigned short count,
56     SimulatorResourceServer::ResourceModelChangedCB callback)
57 {
58     OC_LOG_V(INFO, "Create multiple resource request : config=%s, count=%d", configPath.c_str(),
59              count);
60
61     // Input validation
62     if (configPath.empty())
63     {
64         OC_LOG(ERROR, TAG, "Invalid config file path!");
65         throw InvalidArgsException(SIMULATOR_INVALID_PARAM, "Invalid RAML file path!");
66     }
67
68     if (0 == count)
69     {
70         OC_LOG(ERROR, TAG, "Invalid count value!");
71         throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid count value!");
72     }
73
74     if (!callback)
75     {
76         OC_LOG(ERROR, TAG, "Invalid callback!");
77         throw InvalidArgsException(SIMULATOR_INVALID_CALLBACK, "Invalid callback!");
78     }
79
80     std::vector<SimulatorResourceServerSP> resourceList;
81
82     // Create resources
83     for (unsigned short i = 0; i < count; i++)
84     {
85         OC_LOG_V(INFO, TAG, "Creating resource [%d]", i + 1);
86         SIM_LOG(ILogger::INFO, "Creating resource [" << i + 1 << "]");
87
88         SimulatorResourceServerSP resource = buildResource(configPath, callback);
89         if (!resource)
90         {
91             break;
92         }
93
94         resourceList.push_back(resource);
95     }
96
97     SIM_LOG(ILogger::INFO, "[" << resourceList.size() << " out of " << count <<
98             "] resource(s) created successfully.");
99
100     return resourceList;
101 }
102
103 std::vector<SimulatorResourceServerSP> ResourceManager::getResources(
104     const std::string &resourceType)
105 {
106     std::lock_guard<std::recursive_mutex> lock(m_lock);
107
108     std::vector<SimulatorResourceServerSP> resourceList;
109     for (auto resourceTableEntry : m_resources)
110     {
111         if (!resourceType.empty() && resourceType.compare(resourceTableEntry.first))
112             continue;
113
114         for (auto resourceEntry : resourceTableEntry.second)
115         {
116             resourceList.push_back(resourceEntry.second);
117         }
118     }
119
120     return resourceList;
121 }
122
123 void ResourceManager::deleteResource(const SimulatorResourceServerSP &resource)
124 {
125     if (!resource)
126     {
127         OC_LOG(ERROR, TAG, "Invalid resource object!");
128         throw InvalidArgsException(SIMULATOR_INVALID_PARAM, "Invalid resource object!");
129     }
130
131     std::lock_guard<std::recursive_mutex> lock(m_lock);
132     auto resourceTableEntry = m_resources.find(resource->getResourceType());
133     if (m_resources.end() != resourceTableEntry)
134     {
135         auto resourceEntry = resourceTableEntry->second.find(resource->getURI());
136         if (resourceTableEntry->second.end() != resourceEntry)
137         {
138             SimulatorResourceServerImplSP resourceImpl =
139                 std::dynamic_pointer_cast<SimulatorResourceServerImpl>(resource);
140             resourceImpl->stop();
141             resourceTableEntry->second.erase(resourceEntry);
142             SIM_LOG(ILogger::INFO, "Resource (" << resource->getURI() <<
143                     ") deleted successfully.");
144         }
145     }
146 }
147
148 void ResourceManager::deleteResources(const std::string &resourceType)
149 {
150     std::lock_guard<std::recursive_mutex> lock(m_lock);
151     for (auto & resourceTableEntry : m_resources)
152     {
153         if (!resourceType.empty() && resourceType.compare(resourceTableEntry.first))
154             continue;
155
156         for (auto & resourceEntry : resourceTableEntry.second)
157         {
158             SimulatorResourceServerSP resource = resourceEntry.second;
159             SimulatorResourceServerImplSP resourceImpl =
160                 std::dynamic_pointer_cast<SimulatorResourceServerImpl>(resource);
161             resourceImpl->stop();
162             SIM_LOG(ILogger::INFO, "Resource (" << resource->getURI() <<
163                     ") deleted successfully.");
164         }
165
166         // Erase the entry for resource type from resources list
167         m_resources.erase(resourceTableEntry.first);
168     }
169 }
170
171 /**
172  * This method does not validate the input given, thus Caller of this method must validate
173  * the inputs before invoking this private method.
174  */
175 SimulatorResourceServerSP ResourceManager::buildResource(const std::string &configPath,
176         SimulatorResourceServer::ResourceModelChangedCB callback)
177 {
178     // Create resource based on the RAML file.
179     SimulatorResourceServerImplSP resourceImpl = m_resourceCreator.createResource(configPath);
180     if (!resourceImpl)
181     {
182         OC_LOG(ERROR, TAG, "Failed to create resource!");
183         throw SimulatorException(SIMULATOR_ERROR, "Failed to create resource!");
184     }
185
186     resourceImpl->setModelChangeCallback(callback);
187     resourceImpl->start();
188
189     // Add the resource to resource list table
190     std::lock_guard<std::recursive_mutex> lock(m_lock);
191     SimulatorResourceServerSP resource =
192         std::dynamic_pointer_cast<SimulatorResourceServer>(resourceImpl);
193     m_resources[resourceImpl->getResourceType()].insert(
194         std::pair<std::string, SimulatorResourceServerSP>(resourceImpl->getURI(), resourceImpl));
195
196     SIM_LOG(ILogger::INFO, "Created an OIC resource of type [" <<
197             resourceImpl->getResourceType() << "]");
198     return resourceImpl;
199 }
200
201 /**
202  * This method appends a unique key to the given URI to make the URI unique in simulator.
203  * Example: If input is "/a/light", then the output will be "/a/light/simulator/0" for the first resource
204  * and "/a/light/simulator/1" for the second resource and so on.
205  */
206 std::string ResourceManager::constructURI(const std::string &uri)
207 {
208     std::ostringstream os;
209     os << uri;
210     if (!uri.empty() && '/' != uri[uri.length() - 1])
211         os << '/';
212     os << "simulator/" << m_id++;
213     return os.str();
214 }
215