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
41 RAML::RamlPtr raml = ramlParser->getRamlPtr();
\r
43 // Get the first resource model from RAML
\r
44 RAML::RamlResourcePtr ramlResource;
\r
45 if (0 == raml->getResources().size()
\r
46 || nullptr == (ramlResource = raml->getResources().begin()->second))
\r
48 OC_LOG(ERROR, TAG, "Zero resources detected from RAML!");
\r
52 return buildResource(ramlResource);
\r
55 std::vector<std::shared_ptr<SimulatorResource> > SimulatorResourceFactory::createResource(
\r
56 const std::string &configPath, unsigned int count)
\r
58 std::vector<std::shared_ptr<SimulatorResource>> resources;
\r
60 // Parse the RAML file
\r
61 std::shared_ptr<RAML::RamlParser> ramlParser = std::make_shared<RAML::RamlParser>(configPath);
\r
62 RAML::RamlPtr raml = ramlParser->getRamlPtr();
\r
64 // Get the first resource model from RAML
\r
65 RAML::RamlResourcePtr ramlResource;
\r
66 if (0 == raml->getResources().size()
\r
67 || nullptr == (ramlResource = raml->getResources().begin()->second))
\r
69 OC_LOG(ERROR, TAG, "Zero resources detected from RAML!");
\r
75 std::shared_ptr<SimulatorResource> resource = buildResource(ramlResource);
\r
78 OC_LOG(ERROR, TAG, "Failed to create resource!");
\r
82 resources.push_back(resource);
\r
88 std::shared_ptr<SimulatorSingleResource> SimulatorResourceFactory::createSingleResource(
\r
89 const std::string &name, const std::string &uri, const std::string &resourceType)
\r
91 SimulatorSingleResourceImpl *simpleResource = new SimulatorSingleResourceImpl();
\r
92 simpleResource->setName(name);
\r
93 simpleResource->setURI(uri);
\r
94 simpleResource->setResourceType(resourceType);
\r
95 return std::shared_ptr<SimulatorSingleResource>(simpleResource);
\r
98 std::shared_ptr<SimulatorCollectionResource> SimulatorResourceFactory::createCollectionResource(
\r
99 const std::string &name, const std::string &uri, const std::string &resourceType)
\r
101 SimulatorCollectionResourceImpl *collectionResource = new SimulatorCollectionResourceImpl();
\r
102 collectionResource->setName(name);
\r
103 collectionResource->setURI(uri);
\r
104 collectionResource->setResourceType(resourceType);
\r
105 return std::shared_ptr<SimulatorCollectionResource>(collectionResource);
\r
108 std::shared_ptr<SimulatorResource> SimulatorResourceFactory::buildResource(
\r
109 const std::shared_ptr<RAML::RamlResource> &ramlResource)
\r
111 // Build resource request and respone model schema
\r
112 RequestModelBuilder requestModelBuilder;
\r
113 std::unordered_map<std::string, RequestModelSP> requestModels =
\r
114 requestModelBuilder.build(ramlResource);
\r
116 // Build SimulatorResourceModel from "GET" response schema
\r
117 if (requestModels.end() == requestModels.find("GET"))
\r
119 OC_LOG(ERROR, TAG, "Resource's RAML does not have GET request model!");
\r
123 RequestModelSP getRequestModel = requestModels["GET"];
\r
124 ResponseModelSP getResponseModel = getRequestModel->getResponseModel(200);
\r
125 if (!getResponseModel)
\r
127 OC_LOG(ERROR, TAG, "Resource's RAML does not have response for GET request!");
\r
131 std::shared_ptr<SimulatorResourceModelSchema> responseSchema =
\r
132 getResponseModel->getSchema();
\r
133 if (!responseSchema)
\r
135 OC_LOG(ERROR, TAG, "Failed to get schema from response model!");
\r
139 SimulatorResourceModel resourceModel = responseSchema->buildResourceModel();
\r
141 // Remove the common properties from resource Model
\r
142 std::string resourceURI = ramlResource->getResourceUri();
\r
143 std::string resourceName = ramlResource->getDisplayName();
\r
144 std::string resourceType;
\r
146 // Extracting resource type.
\r
147 if (resourceModel.contains("rt"))
\r
149 resourceType = resourceModel.get<std::string>("rt");
\r
150 resourceModel.remove("rt");
\r
152 else if (resourceModel.contains("resourceType"))
\r
154 resourceType = resourceModel.get<std::string>("resourceType");
\r
155 resourceModel.remove("resourceType");
\r
158 // Construct resource type from uri
\r
159 if(resourceType.empty())
\r
161 std::ostringstream rtString;
\r
162 rtString << "oic.r.";
\r
164 size_t pos = resourceURI.rfind("/");
\r
165 if (pos == std::string::npos)
\r
168 std::string rtName = resourceURI.substr(pos+1);
\r
169 std::transform(rtName.begin(), rtName.end(), rtName.begin(), ::tolower);
\r
170 rtString << rtName;
\r
171 resourceType = rtString.str();
\r
174 // Extracting interface type.
\r
175 std::vector<std::string> interfaceTypes;
\r
176 if (resourceModel.contains("if"))
\r
178 SimulatorResourceModel::TypeInfo typeInfo = resourceModel.getType("if");
\r
179 if(AttributeValueType::STRING == typeInfo.type())
\r
181 interfaceTypes.push_back(resourceModel.get<std::string>("if"));
\r
183 else if(AttributeValueType::VECTOR == typeInfo.type()
\r
184 && AttributeValueType::STRING == typeInfo.baseType()
\r
185 && typeInfo.depth() == 1)
\r
187 interfaceTypes = resourceModel.get<std::vector<std::string>>("if");
\r
188 if (interfaceTypes.size() > 1)
\r
189 interfaceTypes.erase(interfaceTypes.begin()+1, interfaceTypes.end());
\r
192 resourceModel.remove("if");
\r
195 for (auto &requestModel : requestModels)
\r
197 if (requestModel.second)
\r
199 addInterfaceFromQueryParameter((requestModel.second)->getQueryParams("if"),
\r
204 // Remove properties which are not part of resource representation
\r
205 resourceModel.remove("p");
\r
206 resourceModel.remove("n");
\r
207 resourceModel.remove("id");
\r
209 // Create simple/collection resource
\r
210 std::shared_ptr<SimulatorResource> simResource;
\r
211 if (resourceModel.contains("links"))
\r
213 std::shared_ptr<SimulatorCollectionResourceImpl> collectionRes(
\r
214 new SimulatorCollectionResourceImpl());
\r
216 collectionRes->setName(resourceName);
\r
217 collectionRes->setResourceType(resourceType);
\r
218 if (interfaceTypes.size() > 0)
\r
219 collectionRes->setInterface(interfaceTypes);
\r
220 collectionRes->setURI(ResourceURIFactory::getInstance()->makeUniqueURI(resourceURI));
\r
222 // Set the resource model and its schema to simulated resource
\r
223 collectionRes->setResourceModel(resourceModel);
\r
224 collectionRes->setResourceModelSchema(responseSchema);
\r
225 collectionRes->setRequestModel(requestModels);
\r
227 simResource = collectionRes;
\r
231 std::shared_ptr<SimulatorSingleResourceImpl> singleRes(
\r
232 new SimulatorSingleResourceImpl());
\r
234 singleRes->setName(resourceName);
\r
235 singleRes->setResourceType(resourceType);
\r
236 if (interfaceTypes.size() > 0)
\r
237 singleRes->setInterface(interfaceTypes);
\r
238 singleRes->setURI(ResourceURIFactory::getInstance()->makeUniqueURI(resourceURI));
\r
240 // Set the resource model and its schema to simulated resource
\r
241 singleRes->setResourceModel(resourceModel);
\r
242 singleRes->setResourceModelSchema(responseSchema);
\r
243 singleRes->setRequestModel(requestModels);
\r
245 simResource = singleRes;
\r
248 return simResource;
\r
251 void SimulatorResourceFactory::addInterfaceFromQueryParameter(
\r
252 std::vector<std::string> queryParamValue, std::vector<std::string> &interfaceTypes)
\r
254 for (auto &interfaceType : queryParamValue)
\r
256 if (interfaceTypes.end() ==
\r
257 std::find(interfaceTypes.begin(), interfaceTypes.end(), interfaceType))
\r
259 interfaceTypes.push_back(interfaceType);
\r
264 ResourceURIFactory *ResourceURIFactory::getInstance()
\r
266 static ResourceURIFactory s_instance;
\r
267 return &s_instance;
\r
270 ResourceURIFactory::ResourceURIFactory()
\r
273 std::string ResourceURIFactory::makeUniqueURI(const std::string &uri)
\r
275 std::lock_guard<std::mutex> lock(m_lock);
\r
281 std::ostringstream os;
\r
283 if (!uri.empty() && '/' != uri[uri.length() - 1])
\r
286 updateUri(os.str());
\r
290 void ResourceURIFactory::updateUri(const std::string &uri)
\r
292 m_uriList.insert(std::pair<std::string, bool>(uri, true));
\r
295 bool ResourceURIFactory::isUnique(const std::string &uri)
\r
297 if (m_uriList.end() == m_uriList.find(uri))
\r