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
27 #define TAG "SIM_RESOURCE_FACTORY"
\r
29 SimulatorResourceFactory *SimulatorResourceFactory::getInstance()
\r
31 static SimulatorResourceFactory s_instance;
\r
35 std::shared_ptr<SimulatorResource> SimulatorResourceFactory::createResource(
\r
36 const std::string &configPath)
\r
38 // Parse the RAML file
\r
39 std::shared_ptr<RAML::RamlParser> ramlParser = std::make_shared<RAML::RamlParser>(configPath);
\r
40 RAML::RamlPtr raml = ramlParser->getRamlPtr();
\r
42 // Get the first resource model from RAML
\r
43 RAML::RamlResourcePtr ramlResource;
\r
44 if (0 == raml->getResources().size()
\r
45 || nullptr == (ramlResource = raml->getResources().begin()->second))
\r
47 OC_LOG(ERROR, TAG, "Zero resources detected from RAML!");
\r
51 return buildResource(ramlResource);
\r
54 std::vector<std::shared_ptr<SimulatorResource> > SimulatorResourceFactory::createResource(
\r
55 const std::string &configPath, unsigned int count)
\r
57 std::vector<std::shared_ptr<SimulatorResource>> resources;
\r
59 // Parse the RAML file
\r
60 std::shared_ptr<RAML::RamlParser> ramlParser = std::make_shared<RAML::RamlParser>(configPath);
\r
61 RAML::RamlPtr raml = ramlParser->getRamlPtr();
\r
63 // Get the first resource model from RAML
\r
64 RAML::RamlResourcePtr ramlResource;
\r
65 if (0 == raml->getResources().size()
\r
66 || nullptr == (ramlResource = raml->getResources().begin()->second))
\r
68 OC_LOG(ERROR, TAG, "Zero resources detected from RAML!");
\r
74 std::shared_ptr<SimulatorResource> resource = buildResource(ramlResource);
\r
77 OC_LOG(ERROR, TAG, "Failed to create resource!");
\r
81 resources.push_back(resource);
\r
87 std::shared_ptr<SimulatorSingleResource> SimulatorResourceFactory::createSingleResource(
\r
88 const std::string &name, const std::string &uri, const std::string &resourceType)
\r
90 SimulatorSingleResourceImpl *simpleResource = new SimulatorSingleResourceImpl();
\r
91 simpleResource->setName(name);
\r
92 simpleResource->setURI(uri);
\r
93 simpleResource->setResourceType(resourceType);
\r
94 return std::shared_ptr<SimulatorSingleResource>(simpleResource);
\r
97 std::shared_ptr<SimulatorCollectionResource> SimulatorResourceFactory::createCollectionResource(
\r
98 const std::string &name, const std::string &uri, const std::string &resourceType)
\r
100 SimulatorCollectionResourceImpl *collectionResource = new SimulatorCollectionResourceImpl();
\r
101 collectionResource->setName(name);
\r
102 collectionResource->setURI(uri);
\r
103 collectionResource->setResourceType(resourceType);
\r
104 return std::shared_ptr<SimulatorCollectionResource>(collectionResource);
\r
107 SimulatorResourceModel::Attribute SimulatorResourceFactory::buildAttribute(
\r
108 std::shared_ptr<RAML::Properties> propertyElement)
\r
110 std::string propName = propertyElement->getName();
\r
112 // Build representation attribute
\r
113 SimulatorResourceModel::Attribute attribute(propName);
\r
114 switch (propertyElement->getVariantType())
\r
116 case RAML::VariantType::INT:
\r
118 attribute.setValue(propertyElement->getValue<int>());
\r
120 // Convert suppoted values
\r
121 std::vector<int> allowedValues = propertyElement->getAllowedValuesInt();
\r
122 if (allowedValues.size() > 0)
\r
124 SimulatorResourceModel::AttributeProperty attrProp(allowedValues);
\r
125 attribute.setProperty(attrProp);
\r
130 case RAML::VariantType::DOUBLE:
\r
132 attribute.setValue(propertyElement->getValue<double>());
\r
134 // Convert suppoted values
\r
135 std::vector<double> allowedValues = propertyElement->getAllowedValuesDouble();
\r
136 if (allowedValues.size() > 0)
\r
138 SimulatorResourceModel::AttributeProperty attrProp(allowedValues);
\r
139 attribute.setProperty(attrProp);
\r
144 case RAML::VariantType::BOOL:
\r
146 attribute.setValue(propertyElement->getValue<bool>());
\r
148 std::vector<bool> allowedValues = {true, false};
\r
149 SimulatorResourceModel::AttributeProperty attrProp(allowedValues);
\r
150 attribute.setProperty(attrProp);
\r
154 case RAML::VariantType::STRING:
\r
156 attribute.setValue(propertyElement->getValue<std::string>());
\r
158 // Convert suppoted values
\r
159 std::vector<std::string> allowedValues = propertyElement->getAllowedValuesString();
\r
160 if (allowedValues.size() > 0)
\r
162 SimulatorResourceModel::AttributeProperty attrProp(allowedValues);
\r
163 attribute.setProperty(attrProp);
\r
169 // Set the range property if its present
\r
172 propertyElement->getRange(min, max, multipleof);
\r
173 if (min != INT_MIN && max != INT_MAX)
\r
175 SimulatorResourceModel::AttributeProperty attrProp(min, max);
\r
176 attribute.setProperty(attrProp);
\r
181 SimulatorResourceModel SimulatorResourceFactory::buildResourceModel(
\r
182 std::shared_ptr<RAML::Items> item)
\r
184 SimulatorResourceModel itemModel;
\r
185 for ( auto &propElement : item->getProperties())
\r
187 if (!propElement.second)
\r
190 std::string propName = propElement.second->getName();
\r
191 if ("p" == propName || "n" == propName || "id" == propName)
\r
196 if ("array" == propElement.second->getType())
\r
198 std::vector<SimulatorResourceModel> arrayResModel;
\r
199 for ( auto &propertyItem : propElement.second->getItems())
\r
201 arrayResModel.push_back(buildResourceModel(propertyItem));
\r
203 itemModel.add(propName, arrayResModel);
\r
207 itemModel.add(buildAttribute(propElement.second));
\r
213 RAML::RequestResponseBodyPtr SimulatorResourceFactory::getRAMLResponseBody(
\r
214 std::shared_ptr<RAML::RamlResource> ramlResource, RAML::ActionType type, std::string responseCode)
\r
216 // Get the resource representation schema from response body
\r
217 RAML::ActionPtr action = ramlResource->getAction(type);
\r
220 OC_LOG(ERROR, TAG, "Resource does not possess the request!");
\r
224 RAML::ResponsePtr response = action->getResponse(responseCode);
\r
227 OC_LOG(ERROR, TAG, "Resource does not provide valid GET response!");
\r
231 RAML::RequestResponseBodyPtr responseBody = response->getResponseBody("application/json");
\r
234 OC_LOG(ERROR, TAG, "GET response is not of type \"application/json\" ");
\r
238 return responseBody;
\r
241 SimulatorResourceModel SimulatorResourceFactory::buildModelFromResponseBody(
\r
242 RAML::RequestResponseBodyPtr responseBody, std::string &resourceType, std::vector<std::string> &interfaceType)
\r
244 SimulatorResourceModel resModel;
\r
249 // Iterate throgh all resource property and extract information needed for simulating resource.
\r
250 RAML::JsonSchemaPtr resourceProperties = responseBody->getSchema()->getProperties();
\r
253 for ( auto &propertyElement : resourceProperties->getProperties())
\r
255 if (!propertyElement.second)
\r
258 std::string propName = propertyElement.second->getName();
\r
261 if ("rt" == propName || "resourceType" == propName)
\r
263 resourceType = propertyElement.second->getValueString();
\r
268 if ("if" == propName)
\r
270 if ("string" == propertyElement.second->getType())
\r
272 interfaceType.push_back(propertyElement.second->getValueString());
\r
274 else if ("array" == propertyElement.second->getType())
\r
276 for (auto &item : propertyElement.second->getItems())
\r
278 if ("string" == item->getType())
\r
280 interfaceType = item->getAllowedValuesString();
\r
288 // Other Standard properties which should not be part of resource model
\r
289 if ("p" == propName || "n" == propName || "id" == propName)
\r
294 // Add the attribute to resource model
\r
295 if ("array" == propertyElement.second->getType())
\r
297 std::vector<SimulatorResourceModel> arrayResModel;
\r
298 for ( auto &propertyItem : propertyElement.second->getItems())
\r
300 arrayResModel.push_back(buildResourceModel(propertyItem));
\r
302 resModel.add(propName, arrayResModel);
\r
306 resModel.add(buildAttribute(propertyElement.second));
\r
310 if ("array" == resourceProperties->getType())
\r
312 std::vector<SimulatorResourceModel> arrayResModel;
\r
313 for ( auto &propertyItem : resourceProperties->getItems())
\r
315 arrayResModel.push_back(buildResourceModel(propertyItem));
\r
317 resModel.add("links", arrayResModel);
\r
323 std::shared_ptr<SimulatorResource> SimulatorResourceFactory::buildResource(
\r
324 std::shared_ptr<RAML::RamlResource> ramlResource)
\r
328 std::string resourceType, rt;
\r
329 std::vector<std::string> interfaceType, ifType;
\r
331 name = ramlResource->getDisplayName();
\r
332 uri = ramlResource->getResourceUri();
\r
334 RAML::RequestResponseBodyPtr successResponseBody = getRAMLResponseBody(
\r
335 ramlResource, RAML::ActionType::GET, "200");
\r
336 RAML::RequestResponseBodyPtr putErrorResponseBody = getRAMLResponseBody(
\r
337 ramlResource, RAML::ActionType::PUT, "403");
\r
338 RAML::RequestResponseBodyPtr postErrorResponseBody = getRAMLResponseBody(
\r
339 ramlResource, RAML::ActionType::POST, "403");
\r
341 SimulatorResourceModel successResponseModel = buildModelFromResponseBody(
\r
342 successResponseBody, resourceType, interfaceType);
\r
343 SimulatorResourceModel putErrorResponseModel = buildModelFromResponseBody(
\r
344 putErrorResponseBody, rt, ifType);
\r
345 SimulatorResourceModel postErrorResponseModel = buildModelFromResponseBody(
\r
346 postErrorResponseBody, rt, ifType);
\r
348 // Create simple/collection resource
\r
349 std::shared_ptr<SimulatorResource> simResource;
\r
350 if (successResponseModel.containsAttribute("links"))
\r
354 std::shared_ptr<SimulatorCollectionResourceImpl> collectionRes(
\r
355 new SimulatorCollectionResourceImpl());
\r
357 collectionRes->setName(name);
\r
358 collectionRes->setResourceType(resourceType);
\r
359 collectionRes->setInterface(interfaceType);
\r
360 collectionRes->setURI(ResourceURIFactory::getInstance()->constructURI(uri));
\r
362 collectionRes->setResourceModel(successResponseModel);
\r
363 simResource = std::dynamic_pointer_cast<SimulatorResource>(collectionRes);
\r
365 catch (InvalidArgsException &e) {}
\r
371 std::shared_ptr<SimulatorSingleResourceImpl> singleRes(
\r
372 new SimulatorSingleResourceImpl());
\r
374 singleRes->setName(name);
\r
375 singleRes->setResourceType(resourceType);
\r
376 singleRes->setInterface(interfaceType);
\r
377 singleRes->setURI(ResourceURIFactory::getInstance()->constructURI(uri));
\r
379 singleRes->setResourceModel(successResponseModel);
\r
380 singleRes->setPutErrorResponseModel(putErrorResponseModel);
\r
381 singleRes->setPostErrorResponseModel(postErrorResponseModel);
\r
383 simResource = std::dynamic_pointer_cast<SimulatorResource>(singleRes);
\r
385 catch (InvalidArgsException &e) {}
\r
388 return simResource;
\r
391 ResourceURIFactory *ResourceURIFactory::getInstance()
\r
393 static ResourceURIFactory s_instance;
\r
394 return &s_instance;
\r
397 ResourceURIFactory::ResourceURIFactory()
\r
400 std::string ResourceURIFactory::constructURI(const std::string &uri)
\r
402 std::lock_guard<std::mutex> lock(m_lock);
\r
408 std::ostringstream os;
\r
410 if (!uri.empty() && '/' != uri[uri.length() - 1])
\r
413 updateUri(os.str());
\r
417 void ResourceURIFactory::updateUri(const std::string &uri)
\r
419 m_uriList.insert(std::pair<std::string, bool>(uri, true));
\r
422 bool ResourceURIFactory::isUnique(const std::string &uri)
\r
424 if (m_uriList.end() == m_uriList.find(uri))
\r