07ea8de4a67468e6b7c22cf288d0a4c03582e9c3
[platform/upstream/iotivity.git] / service / simulator / src / server / resource_update_automation.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 "resource_update_automation.h"
22 #include "simulator_single_resource_impl.h"
23 #include "attribute_generator.h"
24 #include "simulator_exceptions.h"
25 #include "simulator_logger.h"
26 #include "logger.h"
27
28 #define ATAG "ATTRIBUTE_AUTOMATION"
29 #define RTAG "RESOURCE_AUTOMATION"
30
31 #define SLEEP_FOR(X) if (X > 0) std::this_thread::sleep_for(std::chrono::milliseconds(X));
32
33 AttributeUpdateAutomation::AttributeUpdateAutomation(int id, SimulatorSingleResource *resource,
34         const SimulatorResourceModel::Attribute &attribute, AutomationType type, int interval,
35         updateCompleteCallback callback, std::function<void (const int)> finishedCallback)
36     :   m_resource(resource),
37         m_type(type),
38         m_id(id),
39         m_stopRequested(false),
40         m_updateInterval(interval),
41         m_attributeGen(attribute),
42         m_callback(callback),
43         m_finishedCallback(finishedCallback),
44         m_thread(nullptr)
45 {
46     if (m_updateInterval < 0)
47     {
48         m_updateInterval = 0;
49     }
50 }
51
52 void AttributeUpdateAutomation::start()
53 {
54     m_thread = std::make_shared<std::thread>(&AttributeUpdateAutomation::updateAttribute, this);
55     m_thread->detach();
56 }
57
58 void AttributeUpdateAutomation::stop()
59 {
60     m_stopRequested = true;
61 }
62
63 void AttributeUpdateAutomation::updateAttribute()
64 {
65     SimulatorSingleResourceImpl *resourceImpl =
66         dynamic_cast<SimulatorSingleResourceImpl *>(m_resource);
67
68     if (!resourceImpl)
69         return;
70
71     do
72     {
73         try
74         {
75             SimulatorResourceModel::Attribute attribute;
76             while (!m_stopRequested && true == m_attributeGen.next(attribute))
77             {
78                 try
79                 {
80                     if (false == m_resource->updateAttributeValue(attribute))
81                     {
82                         OC_LOG_V(ERROR, ATAG, "Failed to update the attribute![%s]", attribute.getName().c_str());
83                         continue;
84                     }
85                 }
86                 catch(SimulatorException &e) {}
87
88                 resourceImpl->notifyApp();
89
90                 SLEEP_FOR(m_updateInterval);
91             }
92
93             m_attributeGen.reset();
94         }
95         catch (SimulatorException &e)
96         {
97             break;
98         }
99     }
100     while (!m_stopRequested && AutomationType::RECURRENT == m_type);
101
102     if (!m_stopRequested)
103     {
104         OC_LOG_V(DEBUG, ATAG, "Attribute:%s automation is completed!", m_attrName.c_str());
105         SIM_LOG(ILogger::INFO, "Automation of " << m_attrName << " attribute is completed.");
106     }
107
108     // Notify application through callback
109     if (m_callback)
110         m_callback(m_resource->getURI(), m_id);
111
112     if (m_finishedCallback)
113         m_finishedCallback(m_id);
114 }
115
116 ResourceUpdateAutomation::ResourceUpdateAutomation(int id, SimulatorSingleResource *resource,
117         AutomationType type, int interval, updateCompleteCallback callback,
118         std::function<void (const int)> finishedCallback)
119     :   m_resource(resource),
120         m_type(type),
121         m_id(id),
122         m_stopRequested(false),
123         m_updateInterval(interval),
124         m_callback(callback),
125         m_finishedCallback(finishedCallback),
126         m_thread(nullptr) {}
127
128 void ResourceUpdateAutomation::start()
129 {
130     std::vector<SimulatorResourceModel::Attribute> attributes;
131     for (auto &attributeEntry : m_resource->getResourceModel().getAttributes())
132     {
133         attributes.push_back(attributeEntry.second);
134     }
135
136     if (0 == attributes.size())
137     {
138         OC_LOG(ERROR, RTAG, "Resource has zero attributes!");
139         throw SimulatorException(SIMULATOR_ERROR, "Resource has zero attributes!");
140     }
141
142     m_thread = std::make_shared<std::thread>(&ResourceUpdateAutomation::updateAttributes, this, attributes);
143     m_thread->detach();
144 }
145
146 void ResourceUpdateAutomation::stop()
147 {
148     m_stopRequested = true;
149 }
150
151 void ResourceUpdateAutomation::updateAttributes(
152     std::vector<SimulatorResourceModel::Attribute> attributes)
153 {
154     SimulatorSingleResourceImpl *resourceImpl =
155         dynamic_cast<SimulatorSingleResourceImpl *>(m_resource);
156
157     if (!resourceImpl)
158         return;
159
160     do
161     {
162         AttributeCombinationGen attrCombGen(attributes);
163         SimulatorResourceModel resModel;
164         while (!m_stopRequested && attrCombGen.next(resModel))
165         {
166             for (auto &attributeEntry : resModel.getAttributes())
167             {
168                 try
169                 {
170                     resourceImpl->updateAttributeValue(attributeEntry.second);
171                 }
172                 catch(SimulatorException &e) {}
173             }
174
175             resourceImpl->notifyApp();
176             SLEEP_FOR(m_updateInterval);
177         }
178     }
179     while (!m_stopRequested && AutomationType::RECURRENT == m_type);
180
181     if (!m_stopRequested)
182     {
183         SIM_LOG(ILogger::INFO, "Resource update automation complete [id: " << m_id << "]");
184     }
185
186     // Notify application
187     if (m_callback)
188         m_callback(m_resource->getURI(), m_id);
189
190     if (m_finishedCallback)
191         m_finishedCallback(m_id);
192 }
193