7621a6c557d6cff975ef50f69fb8b799152cda63
[platform/upstream/iotivity.git] / service / simulator / src / service-provider / simulator_resource_creator.cpp
1 /******************************************************************
2  *
3  * Copyright 2015 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  ******************************************************************/
20
21 #include "simulator_resource_creator.h"
22 #include "simulator_logger.h"
23 #include <RamlParser.h>
24 #include "logger.h"
25
26 #define TAG "SIM_RESOURCE_CREATOR"
27
28 unsigned int SimulatorResourceCreator::s_id;
29 SimulatorResourceServerImplSP SimulatorResourceCreator::createResource(
30     const std::string &configPath)
31 {
32     RAML::RamlPtr raml;
33
34     try
35     {
36         RAML::RamlParser *ramlParser = new RAML::RamlParser(configPath);
37         raml = ramlParser->getRamlPtr();
38     }
39     catch (RAML::RamlException &e)
40     {
41         OC_LOG_V(ERROR, TAG, "RAML Exception occured! [%s]", e.what());
42         throw;
43     }
44
45     std::map<std::string, RAML::RamlResourcePtr> ramlResources = raml->getResources();
46     RAML::RamlResourcePtr ramlResource;
47     if (0 == ramlResources.size() || (ramlResource = ramlResources.begin()->second) == nullptr)
48     {
49         OC_LOG(ERROR, TAG, "Zero resources detected from RAML!");
50         return nullptr;
51     }
52
53     if (ramlResource)
54     {
55         SimulatorResourceServerImplSP simResource(new SimulatorResourceServerImpl());
56         simResource->setName(ramlResource->getDisplayName());
57         simResource->setURI(ramlResource->getResourceUri());
58
59         // Get the resource representation schema from GET response body
60         RAML::ActionPtr action = ramlResource->getAction(RAML::ActionType::GET);
61         if (!action)
62         {
63             OC_LOG(ERROR, TAG, "Failed to create resource representation schema as it does not"
64                     "posess the GET request!");
65             return nullptr;
66         }
67
68         RAML::ResponsePtr getResponse = action->getResponse("200");
69         if (!getResponse)
70         {
71             OC_LOG(ERROR, TAG, "Resource does not provide valid GET response!");
72             return nullptr;
73         }
74
75         RAML::RequestResponseBodyPtr responseBody = getResponse->getResponseBody("application/json");
76         if (responseBody)
77         {
78             RAML::JsonSchemaPtr resourceProperties = responseBody->getSchema()->getProperties();
79             for ( auto &propertyElement : resourceProperties->getProperties())
80             {
81                 if (!propertyElement.second)
82                     continue;
83
84                 std::string propName = propertyElement.second->getName();
85                 if ("rt" == propName || "resourceType" == propName)
86                 {
87                     simResource->setResourceType(propertyElement.second->getValueString());
88                     continue;
89                 }
90                 else if ("if" == propName)
91                 {
92                     simResource->setInterfaceType(propertyElement.second->getValueString());
93                     continue;
94                 }
95                 else if ("p" == propName || "n" == propName || "id" == propName)
96                 {
97                     continue;
98                 }
99
100                 // Build representation attribute
101                 SimulatorResourceModel::Attribute attribute(propName);
102                 switch (propertyElement.second->getValueType())
103                 {
104                     case 0: // Integer
105                         attribute.setValue(propertyElement.second->getValue<int>());
106                         break;
107
108                     case 1: // Double
109                         attribute.setValue(propertyElement.second->getValue<double>());
110                         break;
111
112                     case 2: // Boolean
113                         attribute.setValue(propertyElement.second->getValue<bool>());
114                         break;
115
116                     case 3: // String
117                         attribute.setValue(propertyElement.second->getValue<std::string>());
118                         break;
119                 }
120
121                 // Set range/supported values set
122                 int min = 0, max = 0, multipleof = 0;
123                 propertyElement.second->getRange(min, max, multipleof);
124                 attribute.setRange(min, max);
125
126                 if (propertyElement.second->getAllowedValuesSize() > 0)
127                     attribute.setAllowedValues(propertyElement.second->getAllowedValues());
128
129                 simResource->addAttribute(attribute);
130             }
131         }
132
133         simResource->setURI(constructURI(simResource->getURI()));
134         return simResource;
135     }
136
137     return nullptr;
138 }
139
140 /**
141  * This method appends a unique key to the given URI to make the URI unique in simulator.
142  * Example: If input is "/a/light", then the output will be "/a/light/simulator/0" for the first resource
143  * and "/a/light/simulator/1" for the second resource and so on.
144  */
145 std::string SimulatorResourceCreator::constructURI(const std::string &uri)
146 {
147     std::ostringstream os;
148     os << uri;
149     if (!uri.empty() && '/' != uri[uri.length() - 1])
150         os << '/';
151     os << "simulator/" << s_id++;
152     return os.str();
153 }
154