Imported Upstream version 1.1.0
[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 AttributeUpdateAutomation::AttributeUpdateAutomation(
32     int id, std::shared_ptr<SimulatorSingleResourceImpl> resource, const std::string &name,
33     AutoUpdateType type, int interval,
34     const SimulatorSingleResource::AutoUpdateCompleteCallback &callback,
35     std::function<void (const int)> finishedCallback)
36     :   m_id(id),
37         m_attrName(name),
38         m_type(type),
39         m_updateInterval(interval),
40         m_stopRequested(false),
41         m_resource(resource),
42         m_callback(callback),
43         m_finishedCallback(finishedCallback),
44         m_thread(nullptr)
45 {
46     if (m_updateInterval < 0)
47         m_updateInterval = 0;
48 }
49
50 AttributeUpdateAutomation::~AttributeUpdateAutomation()
51 {
52     if (!m_stopRequested)
53         m_thread->detach();
54 }
55
56 void AttributeUpdateAutomation::start()
57 {
58     SimulatorResourceAttribute attribute;
59     if (false == m_resource->getAttribute(m_attrName, attribute))
60     {
61         OIC_LOG(ERROR, ATAG, "Attribute is not present in resource!");
62         throw SimulatorException(SIMULATOR_ERROR, "Attribute is not present in resource!");
63     }
64
65     m_thread.reset(new std::thread(&AttributeUpdateAutomation::updateAttribute, this, attribute));
66 }
67
68 void AttributeUpdateAutomation::stop()
69 {
70     {
71         std::lock_guard<std::mutex> lock(m_lock);
72         m_stopRequested = true;
73     }
74
75     m_condVariable.notify_one();
76     if (m_thread)
77         m_thread->join();
78 }
79
80 void AttributeUpdateAutomation::updateAttribute(SimulatorResourceAttribute attribute)
81 {
82     std::unique_lock<std::mutex> lock(m_lock);
83     std::chrono::system_clock::time_point now;
84
85     AttributeGenerator attributeGen(attribute);
86     do
87     {
88         try
89         {
90             SimulatorResourceAttribute attribute;
91             while (!m_stopRequested && true == attributeGen.next(attribute))
92             {
93                 if (false == m_resource->updateAttributeValue(attribute))
94                     break;
95
96                 // Wait for interval
97                 now = std::chrono::system_clock::now();
98                 m_condVariable.wait_until(lock, now + std::chrono::milliseconds(m_updateInterval),
99                                           [this] { return m_stopRequested; });
100             }
101
102             attributeGen.reset();
103         }
104         catch (SimulatorException &e)
105         {
106             break;
107         }
108     }
109     while (!m_stopRequested && AutoUpdateType::REPEAT == m_type);
110
111     if (!m_stopRequested)
112     {
113         OIC_LOG_V(DEBUG, ATAG, "Attribute:%s automation is completed!", m_attrName.c_str());
114         SIM_LOG(ILogger::INFO, "Attribute automation completed [Name: \"" << m_attrName
115                     << "\", id: " << m_id <<"].");
116     }
117     else
118     {
119         SIM_LOG(ILogger::INFO, "Attribute automation stopped [Name: \"" << m_attrName
120                     << "\", id: " << m_id <<"].");
121     }
122
123     // Notify application through callback
124     if (m_callback)
125         m_callback(m_resource->getURI(), m_id);
126
127     if (m_finishedCallback && !m_stopRequested)
128     {
129         std::thread notifyManager(m_finishedCallback, m_id);
130         notifyManager.detach();
131     }
132 }
133
134 ResourceUpdateAutomation::ResourceUpdateAutomation(
135     int id, std::shared_ptr<SimulatorSingleResourceImpl> resource, AutoUpdateType type, int interval,
136     const SimulatorSingleResource::AutoUpdateCompleteCallback &callback,
137     std::function<void (const int)> finishedCallback)
138     :   m_id(id),
139         m_type(type),
140         m_updateInterval(interval),
141         m_stopRequested(false),
142         m_resource(resource),
143         m_callback(callback),
144         m_finishedCallback(finishedCallback),
145         m_thread(nullptr)
146 {
147     if (m_updateInterval < 0)
148         m_updateInterval = 0;
149 }
150
151 ResourceUpdateAutomation::~ResourceUpdateAutomation()
152 {
153     if (!m_stopRequested)
154         m_thread->detach();
155 }
156
157 void ResourceUpdateAutomation::start()
158 {
159     std::vector<SimulatorResourceAttribute> attributes;
160     for (auto &attributeEntry : m_resource->getAttributes())
161     {
162         attributes.push_back(attributeEntry.second);
163     }
164
165     if (0 == attributes.size())
166     {
167         OIC_LOG(ERROR, RTAG, "Resource has zero attributes!");
168         throw SimulatorException(SIMULATOR_ERROR, "Resource has zero attributes!");
169     }
170
171     m_thread.reset(new std::thread(&ResourceUpdateAutomation::updateAttributes, this, attributes));
172 }
173
174 void ResourceUpdateAutomation::stop()
175 {
176     {
177         std::lock_guard<std::mutex> lock(m_lock);
178         m_stopRequested = true;
179     }
180
181     m_condVariable.notify_one();
182     if (m_thread)
183         m_thread->join();
184 }
185
186 void ResourceUpdateAutomation::updateAttributes(
187     std::vector<SimulatorResourceAttribute> attributes)
188 {
189     std::unique_lock<std::mutex> lock(m_lock);
190     std::chrono::system_clock::time_point now;
191
192     do
193     {
194         AttributeCombinationGen attrCombGen(attributes);
195         SimulatorResourceModel newResModel;
196         while (!m_stopRequested && attrCombGen.next(newResModel))
197         {
198             SimulatorResourceModel updatedResModel;
199             m_resource->updateResourceModel(newResModel, updatedResModel);
200
201             // Wait for interval
202             now = std::chrono::system_clock::now();
203             m_condVariable.wait_until(lock, now + std::chrono::milliseconds(m_updateInterval),
204                                       [this] { return m_stopRequested; });
205         }
206     }
207     while (!m_stopRequested && AutoUpdateType::REPEAT == m_type);
208
209     if (!m_stopRequested)
210     {
211         OIC_LOG_V(DEBUG, RTAG, "Resource update automation complete [id: %d]!", m_id);
212         SIM_LOG(ILogger::INFO, "Resource automation completed [URI: \"" << m_resource->getURI()
213                 << "\", id: " << m_id << "].");
214     }
215     else
216     {
217         SIM_LOG(ILogger::INFO, "Resource automation stopped [URI: \"" << m_resource->getURI()
218                 << "\", id: " << m_id <<"].");
219     }
220
221     // Notify application
222     if (m_callback)
223         m_callback(m_resource->getURI(), m_id);
224
225     if (m_finishedCallback)
226     {
227         std::thread notifyManager(m_finishedCallback, m_id);
228         notifyManager.detach();
229     }
230
231 }
232