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 "RamlParser.h"
\r
25 #include "simulator_logger.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 SimulatorResourceModel::Attribute SimulatorResourceFactory::buildAttribute(
\r
109 std::shared_ptr<RAML::Properties> propertyElement)
\r
111 std::string propName = propertyElement->getName();
\r
113 // Build representation attribute
\r
114 SimulatorResourceModel::Attribute attribute(propName);
\r
115 switch (propertyElement->getVariantType())
\r
117 case RAML::VariantType::INT:
\r
119 attribute.setValue(propertyElement->getValue<int>());
\r
121 // Convert suppoted values
\r
122 std::vector<int> allowedValues = propertyElement->getAllowedValuesInt();
\r
123 if (allowedValues.size() > 0)
\r
125 SimulatorResourceModel::AttributeProperty attrProp(allowedValues);
\r
126 attribute.setProperty(attrProp);
\r
131 case RAML::VariantType::DOUBLE:
\r
133 attribute.setValue(propertyElement->getValue<double>());
\r
135 // Convert suppoted values
\r
136 std::vector<double> allowedValues = propertyElement->getAllowedValuesDouble();
\r
137 if (allowedValues.size() > 0)
\r
139 SimulatorResourceModel::AttributeProperty attrProp(allowedValues);
\r
140 attribute.setProperty(attrProp);
\r
145 case RAML::VariantType::BOOL:
\r
147 attribute.setValue(propertyElement->getValue<bool>());
\r
149 std::vector<bool> allowedValues = {true, false};
\r
150 SimulatorResourceModel::AttributeProperty attrProp(allowedValues);
\r
151 attribute.setProperty(attrProp);
\r
155 case RAML::VariantType::STRING:
\r
157 attribute.setValue(propertyElement->getValue<std::string>());
\r
159 // Convert suppoted values
\r
160 std::vector<std::string> allowedValues = propertyElement->getAllowedValuesString();
\r
161 if (allowedValues.size() > 0)
\r
163 SimulatorResourceModel::AttributeProperty attrProp(allowedValues);
\r
164 attribute.setProperty(attrProp);
\r
170 // Set the range property if its present
\r
173 propertyElement->getRange(min, max, multipleof);
\r
174 if (min != INT_MIN && max != INT_MAX)
\r
176 SimulatorResourceModel::AttributeProperty attrProp(min, max);
\r
177 attribute.setProperty(attrProp);
\r
182 SimulatorResourceModel SimulatorResourceFactory::buildResourceModel(
\r
183 std::shared_ptr<RAML::Items> item)
\r
185 SimulatorResourceModel itemModel;
\r
186 for ( auto &propElement : item->getProperties())
\r
188 if (!propElement.second)
\r
191 std::string propName = propElement.second->getName();
\r
192 if ("rt" == propName || "resourceType" == propName || "if" == propName ||
\r
193 "p" == propName || "n" == propName || "id" == propName )
\r
198 if ("array" == propElement.second->getType())
\r
200 std::vector<SimulatorResourceModel> arrayResModel;
\r
201 for ( auto &propertyItem : propElement.second->getItems())
\r
203 arrayResModel.push_back(buildResourceModel(propertyItem));
\r
205 itemModel.add(propName, arrayResModel);
\r
209 itemModel.add(buildAttribute(propElement.second));
\r
215 std::shared_ptr<SimulatorResource> SimulatorResourceFactory::buildResource(
\r
216 std::shared_ptr<RAML::RamlResource> ramlResource)
\r
220 std::string resourceType;
\r
221 std::vector<std::string> interfaceType;
\r
223 name = ramlResource->getDisplayName();
\r
224 uri = ramlResource->getResourceUri();
\r
226 // Get the resource representation schema from GET response body
\r
227 RAML::ActionPtr action = ramlResource->getAction(RAML::ActionType::GET);
\r
230 OC_LOG(ERROR, TAG, "Resource does not possess the GET request!");
\r
234 RAML::ResponsePtr getResponse = action->getResponse("200");
\r
237 OC_LOG(ERROR, TAG, "Resource does not provide valid GET response!");
\r
241 RAML::RequestResponseBodyPtr responseBody = getResponse->getResponseBody("application/json");
\r
244 OC_LOG(ERROR, TAG, "GET response is not of type \"application/json\" ");
\r
248 // Iterate throgh all resource property and extract information needed for simulating resource
\r
249 RAML::JsonSchemaPtr resourceProperties = responseBody->getSchema()->getProperties();
\r
250 SimulatorResourceModel resModel;
\r
251 for ( auto &propertyElement : resourceProperties->getProperties())
\r
253 if (!propertyElement.second)
\r
256 std::string propName = propertyElement.second->getName();
\r
259 if ("rt" == propName || "resourceType" == propName)
\r
261 resourceType = propertyElement.second->getValueString();
\r
266 if ("if" == propName)
\r
268 if ("string" == propertyElement.second->getType())
\r
270 interfaceType.push_back(propertyElement.second->getValueString());
\r
272 else if ("array" == propertyElement.second->getType())
\r
274 for (auto &item : propertyElement.second->getItems())
\r
276 if ("string" == item->getType())
\r
278 interfaceType = item->getAllowedValuesString();
\r
286 // Other Standard properties which should not be part of resource model
\r
287 if ("p" == propName || "n" == propName || "id" == propName)
\r
292 // Add the attribute to resource model
\r
293 if ("array" == propertyElement.second->getType())
\r
295 std::vector<SimulatorResourceModel> arrayResModel;
\r
296 for ( auto &propertyItem : propertyElement.second->getItems())
\r
298 arrayResModel.push_back(buildResourceModel(propertyItem));
\r
300 resModel.add(propName, arrayResModel);
\r
304 resModel.add(buildAttribute(propertyElement.second));
\r
308 if ("array" == resourceProperties->getType())
\r
310 std::vector<SimulatorResourceModel> arrayResModel;
\r
311 for ( auto &propertyItem : resourceProperties->getItems())
\r
313 arrayResModel.push_back(buildResourceModel(propertyItem));
\r
315 resModel.add("links", arrayResModel);
\r
317 // Create simple/collection resource
\r
318 std::shared_ptr<SimulatorResource> simResource;
\r
319 if (resModel.containsAttribute("links"))
\r
323 std::shared_ptr<SimulatorCollectionResourceImpl> collectionRes(
\r
324 new SimulatorCollectionResourceImpl());
\r
326 collectionRes->setName(name);
\r
327 collectionRes->setResourceType(resourceType);
\r
328 collectionRes->setInterface(interfaceType);
\r
329 if (ResourceURIFactory::getInstance()->isUnique(uri))
\r
330 collectionRes->setURI(uri);
\r
332 collectionRes->setURI(ResourceURIFactory::getInstance()->constructURI(uri));
\r
334 collectionRes->setResourceModel(resModel);
\r
335 simResource = std::dynamic_pointer_cast<SimulatorResource>(collectionRes);
\r
337 catch (InvalidArgsException &e) {}
\r
343 std::shared_ptr<SimulatorSingleResourceImpl> singleRes(
\r
344 new SimulatorSingleResourceImpl());
\r
346 singleRes->setName(name);
\r
347 singleRes->setResourceType(resourceType);
\r
348 singleRes->setInterface(interfaceType);
\r
349 if (ResourceURIFactory::getInstance()->isUnique(uri))
\r
350 singleRes->setURI(uri);
\r
352 singleRes->setURI(ResourceURIFactory::getInstance()->constructURI(uri));
\r
354 singleRes->setResourceModel(resModel);
\r
355 simResource = std::dynamic_pointer_cast<SimulatorResource>(singleRes);
\r
357 catch (InvalidArgsException &e) {}
\r
360 return simResource;
\r
363 ResourceURIFactory *ResourceURIFactory::getInstance()
\r
365 static ResourceURIFactory s_instance;
\r
366 return &s_instance;
\r
369 ResourceURIFactory::ResourceURIFactory()
\r
372 std::string ResourceURIFactory::constructURI(const std::string &uri)
\r
374 std::ostringstream os;
\r
376 if (!uri.empty() && '/' != uri[uri.length() - 1])
\r
382 bool ResourceURIFactory::isUnique(const std::string &uri)
\r
384 if (m_uriList.end() == m_uriList.find(uri))
\r