1 /******************************************************************
\r
3 * Copyright 2015 Samsung Electronics All Rights Reserved.
\r
7 * Licensed under the Apache License, Version 2.0 (the "License");
\r
8 * you may not use this file except in compliance with the License.
\r
9 * You may obtain a copy of the License at
\r
11 * http://www.apache.org/licenses/LICENSE-2.0
\r
13 * Unless required by applicable law or agreed to in writing, software
\r
14 * distributed under the License is distributed on an "AS IS" BASIS,
\r
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
16 * See the License for the specific language governing permissions and
\r
17 * limitations under the License.
\r
19 ******************************************************************/
\r
21 #include "simulator_resource_factory.h"
\r
22 #include "simulator_single_resource_impl.h"
\r
23 #include "simulator_collection_resource_impl.h"
\r
24 #include "simulator_logger.h"
\r
26 #include "request_model_builder.h"
\r
28 #define TAG "SIM_RESOURCE_FACTORY"
\r
30 SimulatorResourceFactory *SimulatorResourceFactory::getInstance()
\r
32 static SimulatorResourceFactory s_instance;
\r
36 std::shared_ptr<SimulatorResource> SimulatorResourceFactory::createResource(
\r
37 const std::string &configPath)
\r
39 // Parse the RAML file
\r
40 std::shared_ptr<RAML::RamlParser> ramlParser = std::make_shared<RAML::RamlParser>(configPath);
\r
43 OIC_LOG(ERROR, TAG, "RAML parser returned NULL!");
\r
47 RAML::RamlPtr raml = ramlParser->getRamlPtr();
\r
50 OIC_LOG(ERROR, TAG, "RAML pointer is NULL!");
\r
54 // Get the first resource model from RAML
\r
55 RAML::RamlResourcePtr ramlResource;
\r
56 if (0 == raml->getResources().size()
\r
57 || nullptr == (ramlResource = raml->getResources().begin()->second))
\r
59 OIC_LOG(ERROR, TAG, "Zero resources detected from RAML!");
\r
63 return buildResource(ramlResource);
\r
66 std::vector<std::shared_ptr<SimulatorResource> > SimulatorResourceFactory::createResource(
\r
67 const std::string &configPath, unsigned int count)
\r
69 std::vector<std::shared_ptr<SimulatorResource>> resources;
\r
71 // Parse the RAML file
\r
72 std::shared_ptr<RAML::RamlParser> ramlParser = std::make_shared<RAML::RamlParser>(configPath);
\r
75 OIC_LOG(ERROR, TAG, "RAML parser returned NULL!");
\r
79 RAML::RamlPtr raml = ramlParser->getRamlPtr();
\r
82 OIC_LOG(ERROR, TAG, "RAML pointer is NULL!");
\r
86 // Get the first resource model from RAML
\r
87 RAML::RamlResourcePtr ramlResource;
\r
88 if (0 == raml->getResources().size()
\r
89 || nullptr == (ramlResource = raml->getResources().begin()->second))
\r
91 OIC_LOG(ERROR, TAG, "Zero resources detected from RAML!");
\r
97 std::shared_ptr<SimulatorResource> resource = buildResource(ramlResource);
\r
100 OIC_LOG(ERROR, TAG, "Failed to create resource!");
\r
104 resources.push_back(resource);
\r
110 std::shared_ptr<SimulatorSingleResource> SimulatorResourceFactory::createSingleResource(
\r
111 const std::string &name, const std::string &uri, const std::string &resourceType)
\r
113 SimulatorSingleResourceImpl *simpleResource = new SimulatorSingleResourceImpl();
\r
114 simpleResource->setName(name);
\r
115 simpleResource->setURI(uri);
\r
116 simpleResource->setResourceType(resourceType);
\r
117 return std::shared_ptr<SimulatorSingleResource>(simpleResource);
\r
120 std::shared_ptr<SimulatorCollectionResource> SimulatorResourceFactory::createCollectionResource(
\r
121 const std::string &name, const std::string &uri, const std::string &resourceType)
\r
123 SimulatorCollectionResourceImpl *collectionResource = new SimulatorCollectionResourceImpl();
\r
124 collectionResource->setName(name);
\r
125 collectionResource->setURI(uri);
\r
126 collectionResource->setResourceType(resourceType);
\r
127 return std::shared_ptr<SimulatorCollectionResource>(collectionResource);
\r
130 std::shared_ptr<SimulatorResource> SimulatorResourceFactory::buildResource(
\r
131 const std::shared_ptr<RAML::RamlResource> &ramlResource)
\r
133 // Build resource request and respone model schema
\r
134 RequestModelBuilder requestModelBuilder;
\r
135 std::unordered_map<std::string, RequestModelSP> requestModels =
\r
136 requestModelBuilder.build(ramlResource);
\r
138 // Build SimulatorResourceModel from "GET" response schema
\r
139 if (requestModels.end() == requestModels.find("GET"))
\r
141 OIC_LOG(ERROR, TAG, "Resource's RAML does not have GET request model!");
\r
145 RequestModelSP getRequestModel = requestModels["GET"];
\r
146 ResponseModelSP getResponseModel = getRequestModel->getResponseModel(200);
\r
147 if (!getResponseModel)
\r
149 OIC_LOG(ERROR, TAG, "Resource's RAML does not have response for GET request!");
\r
153 std::shared_ptr<SimulatorResourceModelSchema> responseSchema =
\r
154 getResponseModel->getSchema();
\r
155 if (!responseSchema)
\r
157 OIC_LOG(ERROR, TAG, "Failed to get schema from response model!");
\r
161 SimulatorResourceModel resourceModel = responseSchema->buildResourceModel();
\r
163 // Remove the common properties from resource Model
\r
164 std::string resourceURI = ramlResource->getResourceUri();
\r
165 std::string resourceName = ramlResource->getDisplayName();
\r
166 std::string resourceType;
\r
168 // Extracting resource type.
\r
169 if (resourceModel.contains("rt"))
\r
171 resourceType = resourceModel.get<std::string>("rt");
\r
172 resourceModel.remove("rt");
\r
174 else if (resourceModel.contains("resourceType"))
\r
176 resourceType = resourceModel.get<std::string>("resourceType");
\r
177 resourceModel.remove("resourceType");
\r
180 // Construct resource type from uri
\r
181 if(resourceType.empty())
\r
183 std::ostringstream rtString;
\r
184 rtString << "oic.r.";
\r
186 size_t pos = resourceURI.rfind("/");
\r
187 if (pos == std::string::npos)
\r
190 std::string rtName = resourceURI.substr(pos+1);
\r
191 std::transform(rtName.begin(), rtName.end(), rtName.begin(), ::tolower);
\r
192 rtString << rtName;
\r
193 resourceType = rtString.str();
\r
196 // Extracting interface type.
\r
197 std::vector<std::string> interfaceTypes;
\r
198 if (resourceModel.contains("if"))
\r
200 SimulatorResourceModel::TypeInfo typeInfo = resourceModel.getType("if");
\r
201 if(AttributeValueType::STRING == typeInfo.type())
\r
203 interfaceTypes.push_back(resourceModel.get<std::string>("if"));
\r
205 else if(AttributeValueType::VECTOR == typeInfo.type()
\r
206 && AttributeValueType::STRING == typeInfo.baseType()
\r
207 && typeInfo.depth() == 1)
\r
209 interfaceTypes = resourceModel.get<std::vector<std::string>>("if");
\r
210 if (interfaceTypes.size() > 1)
\r
211 interfaceTypes.erase(interfaceTypes.begin()+1, interfaceTypes.end());
\r
214 resourceModel.remove("if");
\r
217 for (auto &requestModel : requestModels)
\r
219 if (requestModel.second)
\r
221 addInterfaceFromQueryParameter((requestModel.second)->getQueryParams("if"),
\r
226 // Remove properties which are not part of resource representation
\r
227 resourceModel.remove("p");
\r
228 resourceModel.remove("n");
\r
229 resourceModel.remove("id");
\r
231 // Create simple/collection resource
\r
232 std::shared_ptr<SimulatorResource> simResource;
\r
233 if (resourceModel.contains("links"))
\r
235 std::shared_ptr<SimulatorCollectionResourceImpl> collectionRes(
\r
236 new SimulatorCollectionResourceImpl());
\r
238 collectionRes->setName(resourceName);
\r
239 collectionRes->setResourceType(resourceType);
\r
240 if (interfaceTypes.size() > 0)
\r
241 collectionRes->setInterface(interfaceTypes);
\r
242 collectionRes->setURI(ResourceURIFactory::getInstance()->makeUniqueURI(resourceURI));
\r
244 // Set the resource model and its schema to simulated resource
\r
245 collectionRes->setResourceModel(resourceModel);
\r
246 collectionRes->setResourceModelSchema(responseSchema);
\r
247 collectionRes->setRequestModel(requestModels);
\r
249 simResource = collectionRes;
\r
253 std::shared_ptr<SimulatorSingleResourceImpl> singleRes(
\r
254 new SimulatorSingleResourceImpl());
\r
256 singleRes->setName(resourceName);
\r
257 singleRes->setResourceType(resourceType);
\r
258 if (interfaceTypes.size() > 0)
\r
259 singleRes->setInterface(interfaceTypes);
\r
260 singleRes->setURI(ResourceURIFactory::getInstance()->makeUniqueURI(resourceURI));
\r
262 // Set the resource model and its schema to simulated resource
\r
263 singleRes->setResourceModel(resourceModel);
\r
264 singleRes->setResourceModelSchema(responseSchema);
\r
265 singleRes->setRequestModel(requestModels);
\r
267 simResource = singleRes;
\r
270 return simResource;
\r
273 void SimulatorResourceFactory::addInterfaceFromQueryParameter(
\r
274 std::vector<std::string> queryParamValue, std::vector<std::string> &interfaceTypes)
\r
276 for (auto &interfaceType : queryParamValue)
\r
278 if (interfaceTypes.end() ==
\r
279 std::find(interfaceTypes.begin(), interfaceTypes.end(), interfaceType))
\r
281 interfaceTypes.push_back(interfaceType);
\r
286 ResourceURIFactory *ResourceURIFactory::getInstance()
\r
288 static ResourceURIFactory s_instance;
\r
289 return &s_instance;
\r
292 ResourceURIFactory::ResourceURIFactory()
\r
295 std::string ResourceURIFactory::makeUniqueURI(const std::string &uri)
\r
297 std::lock_guard<std::mutex> lock(m_lock);
\r
303 std::ostringstream os;
\r
305 if (!uri.empty() && '/' != uri[uri.length() - 1])
\r
308 updateUri(os.str());
\r
312 void ResourceURIFactory::updateUri(const std::string &uri)
\r
314 m_uriList.insert(std::pair<std::string, bool>(uri, true));
\r
317 bool ResourceURIFactory::isUnique(const std::string &uri)
\r
319 if (m_uriList.end() == m_uriList.find(uri))
\r