1 //******************************************************************
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
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
11 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
24 * This file contains the resource object APIs provided to the developers.
25 * RCSResourceObject is a part of the server builder module.
27 #ifndef SERVER_RCSRESOURCEOBJECT_H
28 #define SERVER_RCSRESOURCEOBJECT_H
34 #include <boost/atomic.hpp>
36 #include <RCSResourceAttributes.h>
37 #include <RCSResponse.h>
38 #include <RCSRequest.h>
42 class OCResourceRequest;
51 * @brief Thrown when lock has not been acquired.
53 * @see RCSResourceObject::LockGuard
54 * @see RCSResourceObject::getAttributes
56 class NoLockException: public RCSException
59 NoLockException(std::string &&what) : RCSException { std::move(what) } {}
63 * @brief RCSResourceObject represents a resource. It handles any requests from
64 * clients automatically with attributes.
65 * It also provides an auto notification mechanism that notifies to the observers.
67 * Requests are handled automatically by defaultAction of RCSGetResponse and
68 * RCSSetResponse. You can override them and send your own response.
70 * For simple resources, you may want to know whenever attributes are changed
71 * by a set request. In this case, add an AttributeUpdatedListener
72 * with a key interested in instead of overriding SetRequestHandler.
74 class RCSResourceObject
81 * @brief represents the policy of AutoNotify function.
82 * In accord with this policy, observers are notified of attributes that
83 * are changed or updated.
84 * @note Attributes are changed or updated according to execution of some functions
85 * or receipt of 'set-request'.
86 * (functions - RCSResourceObject::setAttribute,
87 * RCSResourceObject::removeAttribute, RCSResourceObject::getAttributes)
89 enum class AutoNotifyPolicy
91 NEVER, /**< Never notify.*/
92 ALWAYS, /**< Always notify.*/
93 UPDATED /**< When attributes are changed, notify.*/
97 * @brief represents the policy of Set-Request Handler.
98 * In accord with this policy, attributes of 'set-request' are created or
101 enum class SetRequestHandlerPolicy
103 NEVER, /**< Server ignore when server is received set-request of attributes
105 ACCEPTANCE /**< Server creates attributes of the new key When server is received
106 set-request of attributes of the new key. */
109 typedef std::shared_ptr< RCSResourceObject > Ptr;
110 typedef std::shared_ptr< const RCSResourceObject > ConstPtr;
114 * @brief This class provides APIs for resource creation, setting properties &
115 * attributes for the constructed resource.
116 * It provides the build() API
117 * which builds a resource and return pointer to RCSResourceObject class.
125 * @brief Constructor.
126 * Sets the resource property values using initializers list.
128 * @param uri Resource URI value to be set
129 * @param type Resource type value to be set
130 * @param interface Interface value to be set
132 *NOTE : m_properties value is by default set to
133 * OC_DISCOVERABLE | OC_OBSERVABLE.
134 * OC_DISCOVERABLE and OC_OBSERVABLE are defined in octypes.h.
136 Builder(const std::string &uri, const std::string &type,
137 const std::string &interface);
140 * Sets the discoverable(OC_DISCOVERABLE) property for the resource.
142 * @param discoverable Whether to be discovered.
144 * @return reference of this Builder
146 *@see OC_DISCOVERABLE
148 Builder &setDiscoverable(bool discoverable);
151 * Sets the observable(OC_OBSERVABLE) property of the resource.
153 * @param observable Whether to be observed.
155 * @return reference of this Builder
159 Builder &setObservable(bool observable);
162 * Sets attribute of the resource.
164 * @param attributes Resource attributes to set
166 * @return reference of this Builder
168 Builder &setAttributes(const RCSResourceAttributes &attributes);
171 * API for setting attributes of the resource.
173 * @param attributes Resource Attributes to set
175 * @return reference of this Builder
177 Builder &setAttributes(RCSResourceAttributes &&attributes);
180 * API for constructing a new RCSResourceObject.
182 * @return Pointer to RCSResourceObject instance created.
184 * @throw PlatformException
185 * It catches exception from registerResource API of OCPlatform and
186 * throws it to developer.
189 RCSResourceObject::Ptr build();
194 std::string m_interface;
195 uint8_t m_properties;
196 RCSResourceAttributes m_resourceAttributes;
201 typedef std::function < RCSGetResponse(const RCSRequest&,
202 RCSResourceAttributes&) > GetRequestHandler;
203 typedef std::function < RCSSetResponse(const RCSRequest&,
204 RCSResourceAttributes&) > SetRequestHandler;
206 typedef std::function < void(const RCSResourceAttributes::Value&,
207 const RCSResourceAttributes::Value &) > AttributeUpdatedListener;
210 RCSResourceObject(RCSResourceObject&&) = delete;
211 RCSResourceObject(const RCSResourceObject&) = delete;
213 RCSResourceObject& operator=(RCSResourceObject&&) = delete;
214 RCSResourceObject& operator=(const RCSResourceObject&) = delete;
216 virtual ~RCSResourceObject();
219 * API for setting a particular attribute value.
221 * @param key name of attribute(used to map the attribute value).
222 * @param value attribute value to be mapped against the key.
224 * @note It is guaranteed thread-safety about attributes.
226 void setAttribute(const std::string& key, const RCSResourceAttributes::Value& value);
231 void setAttribute(const std::string& key, RCSResourceAttributes::Value&& value);
236 void setAttribute(std::string&& key, const RCSResourceAttributes::Value& value);
241 void setAttribute(std::string&& key, RCSResourceAttributes::Value&& value);
244 * API for getting attribute value corresponding to a key(name of that attribute).
246 * @param key name of the attribute value to look for.
248 * @return value of the resource attribute.
250 * @note It is guaranteed thread-safety about attributes.
252 * @throw InvalidKeyException
253 * Throw exception when empty string is provided as Attribute key.
255 RCSResourceAttributes::Value getAttributeValue(const std::string& key) const;
258 * API for retrieving the attribute value associated with the supplied name.
260 * @param key Name of the attribute
262 * @return resource attributes value.
264 * It is guaranteed thread-safety about attributes.
266 template< typename T >
267 T getAttribute(const std::string& key) const
269 WeakGuard lock(*this);
270 return m_resourceAttributes.at(key).get< T >();
274 * API for removing a particular attribute of the resource.
276 * @param key Name of the attribute.
278 * @return If the key exist and matched attribute is deleted, return true.
280 * It is guaranteed thread-safety about attributes.
282 bool removeAttribute(const std::string& key);
285 * API for checking whether a particular attribute is there for a resource or not.
287 * @param key Name of the attribute.
289 * @return If the key exist, return true.
291 * It is guaranteed thread-safety about attributes.
293 bool containsAttribute(const std::string& key) const;
296 * API for getting all the attributes of the RCSResourceObject.
297 * It invokes the expectOwnLock() API to check the owner of the lock using the
299 * If it is not the owner then it throws exception.
301 * @return reference of the attributes of this RCSResourceObject.
303 * @see expectOwnLock()
305 * @throw NoLockException
306 * If you don't do lock with LockGuard, throw exception.
308 RCSResourceAttributes& getAttributes();
313 const RCSResourceAttributes& getAttributes() const;
316 * API for checking whether the particular resource is observable or not
318 virtual bool isObservable() const;
321 * API for checking whether the particular resource is discoverable or not
323 virtual bool isDiscoverable() const;
326 * API for setting the resource's get request handler by the developer/application.
327 * If developer set this handler then all get request will come to the application &
328 * developer can send the response to the client using APIs of RCSGetResponse class.
330 * @param handler Request handler for get requests
332 * @see RCSGetResponse
335 virtual void setGetRequestHandler(GetRequestHandler handler);
338 * API for setting the resource's set request handler by the developer/application.
339 * If developer set this handler then all set request for the resource
340 * will come to the application & developer can send the response to the client
341 * using APIs of RCSSetResponse class.
343 * @param handler Request handler for set requests
345 * @see RCSSetResponse
348 virtual void setSetRequestHandler(SetRequestHandler handler);
351 * API for setting the Listener for a particular attribute update.
353 * @param key The interested attribute's key
354 * @param listener Listener for updation of the interested attribute
357 virtual void addAttributeUpdatedListener(const std::string& key,
358 AttributeUpdatedListener listener);
361 * API for setting the Listener for a particular attribute update.
363 * @param key The interested attribute's key
364 * @param listener Listener for updation of the interested attribute
367 virtual void addAttributeUpdatedListener(std::string&& key,
368 AttributeUpdatedListener listener);
371 * API for removing the handler for a particular attribute update.
373 * @param key The interested attribute's key
376 virtual bool removeAttributeUpdatedListener(const std::string& key);
379 * API for notifying all observers of the RCSResourceObject
380 * with the updated attributes value
382 virtual void notify() const;
385 * API for setting Auto notify policy
387 * @param policy policy to be set
389 * @see AutoNotifyPolicy
392 void setAutoNotifyPolicy(AutoNotifyPolicy policy);
395 * API for getting auto notify policy
397 * @returns AntoNotify policy
399 * @see AutoNotifyPolicy
402 AutoNotifyPolicy getAutoNotifyPolicy() const;
405 * API for setting the policy for a setRequestHandler.
407 * @param policy policy to be set
409 * @see SetRequestHandlerPolicy
412 void setSetRequestHandlerPolicy(SetRequestHandlerPolicy policy);
415 * API for getting the SetRequestHandler Policy.
417 * @returns Property of setRequesthandler
419 * @see SetRequestHandlerPolicy
422 SetRequestHandlerPolicy getSetRequestHandlerPolicy() const;
425 RCSResourceObject(uint8_t, RCSResourceAttributes&&);
427 OCEntityHandlerResult entityHandler(std::shared_ptr< OC::OCResourceRequest >);
429 OCEntityHandlerResult handleRequest(std::shared_ptr< OC::OCResourceRequest >);
430 OCEntityHandlerResult handleRequestGet(std::shared_ptr< OC::OCResourceRequest >);
431 OCEntityHandlerResult handleRequestSet(std::shared_ptr< OC::OCResourceRequest >);
432 OCEntityHandlerResult handleObserve(std::shared_ptr< OC::OCResourceRequest >);
434 void expectOwnLock() const;
436 void autoNotify(bool, AutoNotifyPolicy) const;
437 void autoNotify(bool) const;
439 bool testValueUpdated(const std::string&, const RCSResourceAttributes::Value&) const;
441 template< typename K, typename V >
442 void setAttributeInternal(K&&, V&&);
445 const uint8_t m_properties;
447 OCResourceHandle m_resourceHandle;
448 RCSResourceAttributes m_resourceAttributes;
450 GetRequestHandler m_getRequestHandler;
451 SetRequestHandler m_setRequestHandler;
452 AutoNotifyPolicy m_autoNotifyPolicy;
453 SetRequestHandlerPolicy m_setRequestHandlerPolicy;
455 std::unordered_map< std::string, AttributeUpdatedListener >
456 m_keyAttributesUpdatedListeners;
458 mutable boost::atomic< std::thread::id > m_lockOwner;
459 mutable std::mutex m_mutex;
461 std::mutex m_mutexKeyAttributeUpdate;
465 class RCSResourceObject::LockGuard
468 LockGuard(const RCSResourceObject&);
469 LockGuard(const RCSResourceObject::Ptr);
470 LockGuard(const RCSResourceObject&, AutoNotifyPolicy);
471 LockGuard(const RCSResourceObject::Ptr, AutoNotifyPolicy);
474 LockGuard(const LockGuard&) = delete;
475 LockGuard(LockGuard&&) = delete;
477 LockGuard& operator=(const LockGuard&) = delete;
478 LockGuard& operator=(LockGuard&&) = delete;
484 const RCSResourceObject& m_resourceObject;
486 AutoNotifyPolicy m_autoNotifyPolicy;
490 std::function<void()> m_autoNotifyFunc;
493 class RCSResourceObject::WeakGuard
496 WeakGuard(const RCSResourceObject&);
499 WeakGuard(const WeakGuard&) = delete;
500 WeakGuard(WeakGuard&&) = delete;
502 WeakGuard& operator=(const WeakGuard&) = delete;
503 WeakGuard& operator=(WeakGuard&&) = delete;
505 bool hasLocked() const;
509 const RCSResourceObject& m_resourceObject;
514 #endif // SERVER_RCSRESOURCEOBJECT_H