f7992b1f608f78cc7259186c241f7459cfb9cd2b
[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 attriute update frequency interval
122                 attribute.setUpdateFrequencyTime(propertyElement.second->getUpdateFrequencyTime());
123
124                 // Set range/supported values set
125                 int min = 0, max = 0, multipleof = 0;
126                 propertyElement.second->getRange(min, max, multipleof);
127                 attribute.setRange(min, max);
128
129                 if (propertyElement.second->getAllowedValuesSize() > 0)
130                     attribute.setAllowedValues(propertyElement.second->getAllowedValues());
131
132                 simResource->addAttribute(attribute);
133             }
134         }
135
136         simResource->setURI(constructURI(simResource->getURI()));
137         return simResource;
138     }
139
140     return nullptr;
141 }
142
143 /**
144  * This method appends a unique key to the given URI to make the URI unique in simulator.
145  * Example: If input is "/a/light", then the output will be "/a/light/simulator/0" for the first resource
146  * and "/a/light/simulator/1" for the second resource and so on.
147  */
148 std::string SimulatorResourceCreator::constructURI(const std::string &uri)
149 {
150     std::ostringstream os;
151     os << uri;
152     if (!uri.empty() && '/' != uri[uri.length() - 1])
153         os << '/';
154     os << "simulator/" << s_id++;
155     return os.str();
156 }
157