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 // Extracting interface type.
\r
181 std::vector<std::string> interfaceTypes;
\r
182 if (resourceModel.contains("if"))
\r
184 SimulatorResourceModel::TypeInfo typeInfo = resourceModel.getType("if");
\r
185 if(AttributeValueType::STRING == typeInfo.type())
\r
187 interfaceTypes.push_back(resourceModel.get<std::string>("if"));
\r
189 else if(AttributeValueType::VECTOR == typeInfo.type()
\r
190 && AttributeValueType::STRING == typeInfo.baseType()
\r
191 && typeInfo.depth() == 1)
\r
193 interfaceTypes = resourceModel.get<std::vector<std::string>>("if");
\r
194 if (interfaceTypes.size() > 1)
\r
195 interfaceTypes.erase(interfaceTypes.begin()+1, interfaceTypes.end());
\r
198 resourceModel.remove("if");
\r
201 for (auto &requestModel : requestModels)
\r
203 if (requestModel.second)
\r
205 addInterfaceFromQueryParameter((requestModel.second)->getQueryParams("if"),
\r
210 // Remove properties which are not part of resource representation
\r
211 resourceModel.remove("p");
\r
212 resourceModel.remove("n");
\r
213 resourceModel.remove("id");
\r
215 // Create simple/collection resource
\r
216 std::shared_ptr<SimulatorResource> simResource;
\r
217 if (resourceModel.contains("links"))
\r
219 std::shared_ptr<SimulatorCollectionResourceImpl> collectionRes(
\r
220 new SimulatorCollectionResourceImpl());
\r
222 collectionRes->setName(resourceName);
\r
223 if(!resourceType.empty())
\r
224 collectionRes->setResourceType(resourceType);
\r
225 if (interfaceTypes.size() > 0)
\r
226 collectionRes->setInterface(interfaceTypes);
\r
227 collectionRes->setURI(ResourceURIFactory::getInstance()->makeUniqueURI(resourceURI));
\r
229 // Set the resource model and its schema to simulated resource
\r
230 collectionRes->setResourceModel(resourceModel);
\r
231 collectionRes->setResourceModelSchema(responseSchema);
\r
232 collectionRes->setRequestModel(requestModels);
\r
234 simResource = collectionRes;
\r
238 std::shared_ptr<SimulatorSingleResourceImpl> singleRes(
\r
239 new SimulatorSingleResourceImpl());
\r
241 singleRes->setName(resourceName);
\r
242 if(!resourceType.empty())
\r
243 singleRes->setResourceType(resourceType);
\r
244 if (interfaceTypes.size() > 0)
\r
245 singleRes->setInterface(interfaceTypes);
\r
246 singleRes->setURI(ResourceURIFactory::getInstance()->makeUniqueURI(resourceURI));
\r
248 // Set the resource model and its schema to simulated resource
\r
249 singleRes->setResourceModel(resourceModel);
\r
250 singleRes->setResourceModelSchema(responseSchema);
\r
251 singleRes->setRequestModel(requestModels);
\r
253 simResource = singleRes;
\r
256 return simResource;
\r
259 void SimulatorResourceFactory::addInterfaceFromQueryParameter(
\r
260 std::vector<std::string> queryParamValue, std::vector<std::string> &interfaceTypes)
\r
262 for (auto &interfaceType : queryParamValue)
\r
264 if (interfaceTypes.end() ==
\r
265 std::find(interfaceTypes.begin(), interfaceTypes.end(), interfaceType))
\r
267 interfaceTypes.push_back(interfaceType);
\r
272 ResourceURIFactory *ResourceURIFactory::getInstance()
\r
274 static ResourceURIFactory s_instance;
\r
275 return &s_instance;
\r
278 ResourceURIFactory::ResourceURIFactory()
\r
281 std::string ResourceURIFactory::makeUniqueURI(const std::string &uri)
\r
283 std::lock_guard<std::mutex> lock(m_lock);
\r
289 std::ostringstream os;
\r
291 if (!uri.empty() && '/' != uri[uri.length() - 1])
\r
294 updateUri(os.str());
\r
298 void ResourceURIFactory::updateUri(const std::string &uri)
\r
300 m_uriList.insert(std::pair<std::string, bool>(uri, true));
\r
303 bool ResourceURIFactory::isUnique(const std::string &uri)
\r
305 if (m_uriList.end() == m_uriList.find(uri))
\r