From 980e749f2f52268d90aa980765d846a2cc7cddf8 Mon Sep 17 00:00:00 2001 From: coderhyme Date: Sat, 1 Aug 2015 14:10:11 +0900 Subject: [PATCH] Refactoring for RemoteResourceObject Refine code of RCSRemoteResourceObject, RCSDiscoveryManager and the unittests for them. Also add new logger macro for scope logging. Public exception classes are now located in RCSException header. Change-Id: I20862491e05c21e2a0a5f608a9c615ebd734ed56 Signed-off-by: coderhyme Reviewed-on: https://gerrit.iotivity.org/gerrit/2038 Tested-by: jenkins-iotivity Reviewed-by: Madan Lanka --- .../NotificationManager/src/HostingObject.cpp | 2 +- service/resource-encapsulation/SConscript | 25 +- .../examples/linux/SampleResourceClient.cpp | 14 +- .../include/RCSDiscoveryManager.h | 88 ++- .../resource-encapsulation/include/RCSException.h | 162 ++--- .../include/RCSRemoteResourceObject.h | 654 +++++++++------------ .../include/RCSResourceAttributes.h | 30 +- .../common/primitiveResource/src/RCSException.cpp | 47 ++ .../src/RCSResourceAttributes.cpp | 28 +- .../unittests/ResourceAttributesTest.cpp | 4 +- .../src/common/utils/include/ScopeLogger.h | 91 +++ .../src/resourceClient/RCSDiscoveryManager.cpp | 70 +-- .../src/resourceClient/RCSRemoteResourceObject.cpp | 433 ++++++-------- .../unittests/ResourceClientTest.cpp | 346 +++++++++++ .../unittests/ResourceClient_Test.cpp | 381 ------------ .../resource-encapsulation/unittests/SConscript | 22 +- 16 files changed, 1174 insertions(+), 1223 deletions(-) create mode 100644 service/resource-encapsulation/src/common/utils/include/ScopeLogger.h create mode 100644 service/resource-encapsulation/unittests/ResourceClientTest.cpp delete mode 100644 service/resource-encapsulation/unittests/ResourceClient_Test.cpp diff --git a/service/notification-manager/NotificationManager/src/HostingObject.cpp b/service/notification-manager/NotificationManager/src/HostingObject.cpp index c28de84..8a615d9 100644 --- a/service/notification-manager/NotificationManager/src/HostingObject.cpp +++ b/service/notification-manager/NotificationManager/src/HostingObject.cpp @@ -41,7 +41,7 @@ void OIC_HOSTING_LOG(LogLevel level, const char * format, ...) HostingObject::HostingObject() : remoteObject(nullptr), mirroredServer(nullptr), - remoteState(ResourceState::NOT_MONITORING), + remoteState(ResourceState::NONE), pStateChangedCB(nullptr), pDataUpdateCB(nullptr), pDestroyCB(nullptr), pSetRequestHandler(nullptr) { diff --git a/service/resource-encapsulation/SConscript b/service/resource-encapsulation/SConscript index dfd93a7..6c32a81 100644 --- a/service/resource-encapsulation/SConscript +++ b/service/resource-encapsulation/SConscript @@ -33,13 +33,13 @@ SConscript('src/resourceContainer/SConscript') ###################################################################### if env.get('RELEASE'): - env.AppendUnique(CCFLAGS = ['-Os']) - env.AppendUnique(CPPDEFINES = ['NDEBUG']) + env.AppendUnique(CCFLAGS = ['-Os']) + env.AppendUnique(CPPDEFINES = ['NDEBUG']) else: - env.AppendUnique(CCFLAGS = ['-g']) + env.AppendUnique(CCFLAGS = ['-g']) if env.get('LOGGING'): - env.AppendUnique(CPPDEFINES = ['TB_LOG']) + env.AppendUnique(CPPDEFINES = ['TB_LOG']) # Add third party libraries lib_env = env.Clone() @@ -51,12 +51,14 @@ target_os = env.get('TARGET_OS') ###################################################################### # Build flags ###################################################################### -resourceClient_env.AppendUnique(CPPPATH = ['include']) -resourceClient_env.AppendUnique(CPPPATH = ['src/common/primitiveResource/include']) -resourceClient_env.AppendUnique(CPPPATH = ['src/common/expiryTimer/include']) -resourceClient_env.AppendUnique(CPPPATH = ['src/common/expiryTimer/src']) -resourceClient_env.AppendUnique(CPPPATH = ['src/resourceBroker/include']) -resourceClient_env.AppendUnique(CPPPATH = ['src/resourceCache/include']) +resourceClient_env.AppendUnique(CPPPATH = [ + 'include', + 'src/common/primitiveResource/include', + 'src/common/expiryTimer/include', + 'src/common/utils/include', + 'src/resourceBroker/include', + 'src/resourceCache/include' +]) resourceClient_env.PrependUnique(LIBS = ['oc', 'rcs_common', 'octbstack', 'gnustl_shared','oc_logger', 'compatibility', 'log']) @@ -77,6 +79,7 @@ resourceClient_env.AppendUnique(LIBS = ['dl']) BROKER_SRC_DIR = 'src/resourceBroker/src/' CACHE_SRC_DIR = 'src/resourceCache/src/' RESOURCECLIENT_DIR = 'src/resourceClient/' + client_src = [ BROKER_SRC_DIR + 'DeviceAssociation.cpp', BROKER_SRC_DIR + 'DevicePresence.cpp', @@ -85,7 +88,7 @@ client_src = [ CACHE_SRC_DIR + 'DataCache.cpp', CACHE_SRC_DIR + 'ResourceCacheManager.cpp', RESOURCECLIENT_DIR + 'RCSDiscoveryManager.cpp', - RESOURCECLIENT_DIR + 'RCSRemoteResourceObject.cpp' + RESOURCECLIENT_DIR + 'RCSRemoteResourceObject.cpp' ] ResourceClientsdk = resourceClient_env.StaticLibrary('rcs_client', client_src) resourceClient_env.InstallTarget(ResourceClientsdk , 'librcs_client') diff --git a/service/resource-encapsulation/examples/linux/SampleResourceClient.cpp b/service/resource-encapsulation/examples/linux/SampleResourceClient.cpp index 81a73d5..924e751 100644 --- a/service/resource-encapsulation/examples/linux/SampleResourceClient.cpp +++ b/service/resource-encapsulation/examples/linux/SampleResourceClient.cpp @@ -37,8 +37,8 @@ void OnResourceStateChanged(ResourceState resourceState) cout << "\nOnResourceStateChanged callback" << std::endl; - if (resourceState == ResourceState::NOT_MONITORING) - cout << "State changed to : NOT_MONITORING" << std::endl; + if (resourceState == ResourceState::NONE) + cout << "State changed to : NONE" << std::endl; else if (resourceState == ResourceState::ALIVE) cout << "State changed to : ALIVE" << std::endl; else if (resourceState == ResourceState::REQUESTED) @@ -316,17 +316,13 @@ int main() } else { - CacheState state = resource->getResourceCacheState(); + CacheState state = resource->getCacheState(); if (state == CacheState ::READY) cout << "Current Cache State : " << "CACHE_STATE ::READY" << std::endl; - else if (state == CacheState ::READY_YET) - cout << "Current Cache State : " << "CACHE_STATE ::READY_YET" << std::endl; + else if (state == CacheState ::UNREADY) + cout << "Current Cache State : " << "CACHE_STATE ::UNREADY" << std::endl; else if (state == CacheState ::LOST_SIGNAL) cout << "Current Cache State : " << "CACHE_STATE ::LOST_SIGNAL" << std::endl; - else if (state == CacheState ::DESTROYED) - cout << "Current Cache State : " << "CACHE_STATE ::DESTROYED" << std::endl; - else if (state == CacheState ::UPDATING) - cout << "Current Cache State : " << "CACHE_STATE ::UPDATING" << std::endl; else if (state == CacheState ::NONE) cout << "Current Cache State : " << "CACHE_STATE ::NONE" << std::endl; } diff --git a/service/resource-encapsulation/include/RCSDiscoveryManager.h b/service/resource-encapsulation/include/RCSDiscoveryManager.h index 47e0b0d..d73a7be 100644 --- a/service/resource-encapsulation/include/RCSDiscoveryManager.h +++ b/service/resource-encapsulation/include/RCSDiscoveryManager.h @@ -25,69 +25,65 @@ * */ -#ifndef RCS_DISCOVERYMANAGER_H_ -#define RCS_DISCOVERYMANAGER_H_ +#ifndef RCSDISCOVERYMANAGER_H +#define RCSDISCOVERYMANAGER_H -#include "RCSRemoteResourceObject.h" +#include +#include namespace OIC { namespace Service { - /* - * Forward Declaration of RCSAddress Class - */ + class RCSRemoteResourceObject; class RCSAddress; /** - * @class RCSDiscoveryManager - * @brief This class contains the resource discovery method. - * - */ + * This class contains the resource discovery method. + * + * @see RCSRemoteResourceObject + */ class RCSDiscoveryManager { - public: + public: - /** - * Typedef for callback of discoverResource API - */ - typedef std::function< void( std::shared_ptr< RCSRemoteResourceObject>) > - OnResourceDiscoveredCallback; - - /** - * API for getting RCSDiscoveryManager instance. - * - * @return RCSDiscoveryManager - Instance of RCSDiscoveryManager class - */ - static RCSDiscoveryManager *getInstance(); + /** + * Typedef for callback of discoverResource API + * + * @see discoverResource + */ + typedef std::function< void(std::shared_ptr< RCSRemoteResourceObject >) > + ResourceDiscoveredCallback; - /** - * API for discovering the resource of Interest. - * - * @param address - RCSAddress object - * @param resourceURI - uri of resource to be searched - * @param cb - callback to obtain discovered resource - * - * @throw InvalidParameterException : This API throws the InvalidParameterException if any of - * the parameter is invalid. - * @see RCSAddress - */ - void discoverResource(const RCSAddress &address, const std::string &resourceURI, - OnResourceDiscoveredCallback cb); - private: + /** + * Returns RCSDiscoveryManager instance. + * + */ + static RCSDiscoveryManager* getInstance(); - /** - * Constructor for RCSDiscoveryManager. - */ - RCSDiscoveryManager() = default; + /** + * API for discovering the resource of Interest. + * + * @param address A RCSAddress object + * @param resourceURI The uri of resource to be searched + * @param cb A callback to obtain discovered resource + * + * @throws InvalidParameterException If any parameter is invalid. + * + * @note The callback will be invoked in an internal thread. + * + * @see RCSAddress + * + */ + void discoverResource(const RCSAddress& address, const std::string& resourceURI, + ResourceDiscoveredCallback cb); - /** - * Destructor for RCSDiscoveryManager. - */ - ~RCSDiscoveryManager() = default; + private: + RCSDiscoveryManager() = default; + ~RCSDiscoveryManager() = default; }; } } -#endif //RCS_DISCOVERYMANAGER_H_ +#endif // RCSDISCOVERYMANAGER_H diff --git a/service/resource-encapsulation/include/RCSException.h b/service/resource-encapsulation/include/RCSException.h index a47b1e4..256ba59 100644 --- a/service/resource-encapsulation/include/RCSException.h +++ b/service/resource-encapsulation/include/RCSException.h @@ -37,85 +37,113 @@ namespace OIC { /** - * @class RCSException - * @brief This class helps to throw wide range of exception to the application/developers. - * It inherits the standard exception class. + * The base exception class for resource encapsulation. * */ class RCSException: public std::exception { - public: - /** - * Default Constructor - */ - RCSException(); - - /** - * Parametrized Constructor to set exception description as a string. - * - * @param what - exception description - */ - explicit RCSException(const std::string &what); - - /** - * Parametrized Constructor to set exception description as a string. - * - * @param what - exception description - */ - explicit RCSException(std::string &&what); - - /** - * virtual destructor - */ - virtual ~RCSException() noexcept {} - - /** - * API for returning the exception description in string format - * - * @return const char* - exception description - */ - virtual const char *what() const noexcept; - - private: - /** - * Exception description - */ - std::string m_what; + public: + + /** + * Constructs an exception with an empty description. + */ + RCSException(); + + /** + * Constructs an exception with a description. + * + * @param what The description for the error. + */ + explicit RCSException(const std::string &what); + + /** + * @overload + */ + explicit RCSException(std::string &&what); + + virtual ~RCSException() noexcept; + + /** + * Returns the exception description. + * + */ + virtual const char *what() const noexcept; + + private: + /** + * Exception description + */ + const std::string m_what; }; /** - * @class PlatformException - * @brief This class helps in throwing platform exception to the application/developers. - * It inherits from RCSException class. + * Thrown when OC layer returns an error. * - * NOTE: OCStackResult is defined in octypes.h. */ class PlatformException: public RCSException { - public: - explicit PlatformException(OCStackResult reason); - - /** - * API for getting exception code. - * - * @return OCStackResult - exception code. - * - */ - OCStackResult getReasonCode() const; - /** - * API for getting exception reason. - * - * @return string - exception reason as a string. - * - */ - std::string getReason() const; - - private: - /* - * reason for the exception, stored as OCStackResult value. - */ - OCStackResult m_reason; + public: + explicit PlatformException(OCStackResult reason); + + /** + * Returns the reason. + * + */ + OCStackResult getReasonCode() const; + + /** + * Returns the reason description. + * + */ + std::string getReason() const; + + private: + OCStackResult m_reason; }; + + /** + * Thrown when a request is not acceptable. + * + */ + class BadRequestException: public RCSException + { + public: + explicit BadRequestException(const std::string& what); + explicit BadRequestException(std::string&& what); + }; + + /** + * Thrown when a parameter is not valid. + * + */ + class InvalidParameterException: public RCSException + { + public: + explicit InvalidParameterException(const std::string& what); + explicit InvalidParameterException(std::string&& what); + }; + + /** + * Thrown when getting value with wrong template parameter. + */ + class BadGetException: public RCSException + { + public: + explicit BadGetException(const std::string& what); + explicit BadGetException(std::string&& what); + }; + + /** + * Thrown when a key is invalid. + * + */ + class InvalidKeyException: public RCSException + { + public: + explicit InvalidKeyException(const std::string& what); + explicit InvalidKeyException(std::string&& what); + }; + } } diff --git a/service/resource-encapsulation/include/RCSRemoteResourceObject.h b/service/resource-encapsulation/include/RCSRemoteResourceObject.h index 5f7846d..0503488 100644 --- a/service/resource-encapsulation/include/RCSRemoteResourceObject.h +++ b/service/resource-encapsulation/include/RCSRemoteResourceObject.h @@ -22,14 +22,13 @@ * @file * * This file contains the Resource Client APIs provided to the developers. - * It is a common API layer for the Resource Broker and Resource Cache module of Resource - * Manipulation layer. */ -#ifndef RCS_RemoteResourceObject_H -#define RCS_RemoteResourceObject_H +#ifndef RCSREMOTERESOURCEOBJECT_H +#define RCSREMOTERESOURCEOBJECT_H + +#include -#include #include "RCSResourceAttributes.h" namespace OIC @@ -37,384 +36,315 @@ namespace OIC namespace Service { /** - * Cache State enum specify the state of the Cache. - */ + * The states of caching. + * + * @see startCaching + * @see getCacheState + */ enum class CacheState { - READY = 0, - READY_YET, - LOST_SIGNAL, - DESTROYED, - UPDATING, - NONE + NONE, /**< Caching is not started.*/ + UNREADY, /**< Caching is started, but the data is not ready yet. + This is the default state after startCaching. */ + READY, /**< The data is ready.*/ + LOST_SIGNAL, /**< Failed to reach the resource. */ }; /** - * Resource State enum specify the state of the resource. - */ + * The states of monitoring. + * + * @see startMonitoring + * @see getState + */ enum class ResourceState { - NOT_MONITORING, - ALIVE, REQUESTED, - LOST_SIGNAL, - DESTROYED + NONE, /**< Monitoring is not started.*/ + REQUESTED, /**< Monitoring is started and checking state is in progress. + This is the default state after startMonitoring. */ + ALIVE, /**< The resource is alive. */ + LOST_SIGNAL, /**< Failed to reach the resource. */ + DESTROYED /**< The resource is deleted. */ }; - /* - * Forward Declaration of Classes - */ - class RCSException; - class RCSRemoteResourceObject; class PrimitiveResource; /** - * @class BadRequestException - * @brief This class is used to throw exception to the upper layer if request is invalid. - * It is inherited from RCSException class. * - */ - class BadRequestException: public RCSException - { - public: - BadRequestException(const std::string &what) : RCSException { what } {} - BadRequestException(std::string &&what) : RCSException { std::move(what) } {} - }; - - /** - * @class InvalidParameterException - * @brief This class is used to throw exception to the upper layer if parameter is invalid. - * It is inherited from RCSException class. - */ - class InvalidParameterException: public RCSException - { - public: - InvalidParameterException(const std::string &what) : RCSException { what } {} - InvalidParameterException(std::string &&what) : RCSException { std::move(what) } {} - }; - - /** - * @class RCSRemoteResourceObject - * @brief This class is an interaction point between Resource - * and the developers. Developer will get the RCSRemoteResourceObject by calling the - * discoverResource() API of "RCSDiscoveryManager" class. + * The resource can be discovered with discoverResource. + * This class is an interaction point between Resource + * and the developers. Developer will get the RCSRemoteResourceObject + * by calling RCSDiscoveryManager::discoverResource. * * @see RCSDiscoveryManager * */ class RCSRemoteResourceObject { - public: - - /** - * Constructor for RCSRemoteResourceObject - */ - RCSRemoteResourceObject(std::shared_ptr pResource); - - /** - * Typedef for callback of startMonitoring API - * - * @see ResourceState - */ - typedef std::function< void(ResourceState) > ResourceStateChangedCallback; - - /** - * Typedef for callback of startCaching API - * - * @see RCSResourceAttributes - */ - typedef std::function< void(const RCSResourceAttributes &) > CacheUpdatedCallback; - - /** - * Typedef for callback of getRemoteAttributes API - * - * @see RCSResourceAttributes - */ - typedef std::function< void(const RCSResourceAttributes &) > - RemoteAttributesReceivedCallback; - - - /** - * Typedef for callback of setRemoteAttributes API - * - * @see RCSResourceAttributes - */ - typedef std::function< void(const RCSResourceAttributes &) > + public: + typedef std::shared_ptr< RCSRemoteResourceObject > Ptr; + + /** + * Typedef for callback of startMonitoring API + * + * @see ResourceState + */ + typedef std::function< void(ResourceState) > StateChangedCallback; + + /** + * Typedef for callback of startCaching API + * + * @see RCSResourceAttributes + */ + typedef std::function< void(const RCSResourceAttributes&) > CacheUpdatedCallback; + + /** + * Typedef for callback of getRemoteAttributes API + * + * @see RCSResourceAttributes + */ + typedef std::function< void(const RCSResourceAttributes&) > + RemoteAttributesGetCallback; + + /** + * Typedef for callback of setRemoteAttributes API + * + * @see RCSResourceAttributes + */ + typedef std::function< void(const RCSResourceAttributes&) > RemoteAttributesSetCallback; - /** - * Check monitoring state. - * - * @details This API checks the current monitoring state for the resource of interest. - * - * @return bool - true if monitoring the resource otherwise false. - */ - bool isMonitoring() const; - - /** - * Check current Caching state. - * - * @details This API checks the current caching state for the resource of interest. - * - * @return bool - true if Caching started otherwise false. - */ - - bool isCaching() const; - - /** - * Check whether reosurce is observable or not. - * - * @details This API checks the observable property of the resource. - * - * @return bool - true if observable otherwise false. - */ - bool isObservable() const; - - /** - * Start Monitoring the resource. - * - * @details This API will start monitoring the resource of interest. - * Once this API is called it will check whether the particular resource - * is available or not. It will provide the changed resource state in the callback. - * - * @param cb - callback to get changed resource state. - * - * @throw InvalidParameterException - * - * @see ResourceStateChangedCallback - * @see ResourceState - * - * NOTE: Developer can call this API any number of time. Developer should take care - * of Synchronization as ResourceStateChangedCallback is asynchronous. - * This function throws the InvalidParameterException if the callback is NULL or not valid. - */ - void startMonitoring(ResourceStateChangedCallback cb); - - /** - * Stop monitoring the resource. - * - * @details This API will stop monitoring the resource of interest it means it will stop to look - * for the resource presence in the network. - * - * NOTE: If startMonitoring() is not being called & directly this API is called it will do nothing. - * Developer can call this API any number of time. It will not results in any kind of warning. - * - */ - void stopMonitoring(); - - /** - * Provides the current resource state. Resource state is an enum class. - * - * @return ResourceState - current state of the resource. - * - * @throw BadRequestException - * - * @see ResourceState - */ - ResourceState getState() const ; - - /** - * Start caching data for the resource of interest. - * - * @details This API will start data caching for the resource of interest. - * Once caching started it will look for the data updation on the resource of interest - * & updates the cache data accordingly. It provides the cached data on demand. - * - * @see getCachedAttributes() - * @see getCachedAttribute( const std::string &) - * - * NOTE: developer can get the cached data by calling getCachedAttributes() - * or getCachedAttribute() API - */ - void startCaching(); - - /** - * Start caching data for the resource of interest. - * - * @details This API will start data caching for the resource of interest. - * Once caching started it look for the data updation on the resource of interest & - * updates the cached data accordingly Whenever data is updated in the cache, it - * provides the updated data to the application/caller. - * - * @param cb - callback to get updated resourceAttributes. - * - * @throw InvalidParameterException - * - * @see CacheUpdatedCallback - * - * NOTE: Developer can call this API any number of time. Developer should - * take care of Synchronization as CacheUpdatedCallback is asynchronous. - * This function throws the InvalidParameterException if the callback is NULL or not valid. - * - */ - void startCaching(CacheUpdatedCallback cb); - - /** - * Provides the current cache state for the resource of interest. CacheState is the enum class. - * - * @return CacheState - Current state of the Cache. - * - * @throw BadRequestException - * - * @see CacheState - * - */ - CacheState getResourceCacheState(); - - /** - * Stop data caching for the resource of interest. - * - * @details This API will stop caching the data for the resource of interest. - * - * NOTE: If startCaching() or startCaching(CacheUpdatedCallback) is not being called & - * directly this API is called it will do nothing. - * Developer can call this API any number of time, it will not results in any warning. - * - */ - void stopCaching(); - - /** - * Refresh the cache. - * - * @details This API will refresh the cache, i.e. it will get the latest data from the server. - * - */ - void refreshCache() ; - - /** - * Get the cached RCSResourceAttributes data. - * - * @pre startCaching() or startCaching(CacheUpdatedCallback) API should be called. - * - * @return RCSResourceAttributes - cached resourceAttribute - * - * @throw BadRequestException - * - * @see startCaching() - * @see startCaching(CacheUpdatedCallback) - * @see RCSResourceAttributes - * - * NOTE: If startCaching() or startCaching(CacheUpdatedCallback) is not being called & - * directly this API is called it will throw the - * BadRequestException. - */ - RCSResourceAttributes getCachedAttributes() const; - - /** - * Get a particular cached ResourceAttribute value. - * - * @pre startCaching() or startCaching(CacheUpdatedCallback) API should be called. - * - * @return RCSResourceAttributes::Value - requested attribute Value - * - * @throw BadRequestException - * - * @see startCaching() - * @see startCaching(CacheUpdatedCallback) - * @see RCSResourceAttributes::Value - * - * NOTE: If startCaching() or startCaching(CacheUpdatedCallback) is not being called & - * directly this API is called it will throw the BadRequestException. - * - */ - RCSResourceAttributes::Value getCachedAttribute( const std::string &) ; - - /** - * Get resource attributes. - * - * @details This API send a get request to the resource of interest and provides the attributes - * to the caller in the RemoteAttributesReceivedCallback. - * - * - * @throw InvalidParameterException - * - * @see RCSResourceAttributes::Value - */ - void getRemoteAttributes(RemoteAttributesReceivedCallback cb); - - /** - * Set resource attributes. - * - * @details This API send a set request to the resource of interest and provides the updated - * attributes to the caller in the RemoteAttributesSetCallback. - * - * @param attributes - resourceAttributes data to set - * @param cb - callback on setting resourceAttributes data. - * - * @throw InvalidParameterException - * - */ - void setRemoteAttributes(const RCSResourceAttributes &attributes, RemoteAttributesSetCallback cb); - - /** - * Get resource uri. - * - * @return string - uri of the Resource - */ - std::string getUri() const; - - /** - * Get resource address. - * - * @return string - address of the Resource - */ - std::string getAddress() const; - - /** - * Get resource types. - * - * @return vector - resource types - */ - std::vector< std::string > getTypes() const; - - /** - * Get resource interfaces. - * - * @return vector - resource interfaces - */ - std::vector< std::string > getInterfaces() const; - - private: - - /** - * Typedef for Cache ID - */ - typedef int CacheID; - - /** - * Typedef for Broker ID - */ - typedef unsigned int BrokerID; - - /** - * Flag to check monitoring state. - */ - bool m_monitoringFlag; - - /** - * Flag to check caching state. - */ - bool m_cachingFlag; - - /** - * Flag to check observing state. - */ - bool m_observableFlag; - - /** - * PrimitiveResource - */ - std::shared_ptr m_primitiveResource; - - /** - * caching identification number. - */ - CacheID m_cacheId; - - /** - * Broker identification number. - */ - BrokerID m_brokerId; + private: + typedef int CacheID; + typedef unsigned int BrokerID; + + public: + //! @cond + RCSRemoteResourceObject(std::shared_ptr< PrimitiveResource >); + //! @endcond + + ~RCSRemoteResourceObject(); + + /** + * Returns whether monitoring is enabled. + * + * @see startMonitoring() + */ + bool isMonitoring() const; + + /** + * Returns whether caching is enabled. + * + * @see startCaching() + */ + + bool isCaching() const; + + /** + * Returns whether the resource is observable. + * + */ + bool isObservable() const; + + /** + * Starts monitoring the resource. + * + * Monitoring provides a feature to check the presence of a resource, + * even when the server is not announcing Presence using startPresnece. + * + * @param cb A Callback to get changed resource state. + * + * @throws InvalidParameterException If cb is an empty function or null. + * @throws BadRequestException If monitoring is already started. + * + * @note The callback will be invoked in an internal thread. + * + * @see StateChangedCallback + * @see ResourceState + * @see isMonitoring() + * @see stopMonitoring() + * + */ + void startMonitoring(StateChangedCallback cb); + + /** + * Stops monitoring the resource. + * + * It does nothing if monitoring is not started. + * + * @see startMonitoring() + * + */ + void stopMonitoring(); + + /** + * Returns the current state of the resource. + * + * @see startMonitoring + */ + ResourceState getState() const; + + /** + * Starts caching attributes of the resource. + * + * This will start data caching for the resource. + * Once caching started it will look for the data updation on the resource + * and updates the cache data accordingly. + * + * It is equivalent to calling startCaching(CacheUpdatedCallback) with an empty function. + * + * @see getCacheState() + * @see getCachedAttributes() + * @see getCachedAttribute(const std::string&) const + * + * @throws BadRequestException + * + */ + void startCaching(); + + /** + * Starts caching attributes for the resource. + * + * This will start data caching for the resource. + * Once caching started it will look for the data updation on the resource and + * updates the cached data accordingly. + * + * @param cb If non-empty function, it will be invoked whenever the cache updated. + * + * @throws BadRequestException If caching is already started. + * + * @note The callback will be invoked in an internal thread. + * + * @see CacheUpdatedCallback + * @see getCacheState() + * @see isCachedAvailable() + * @see getCachedAttributes() + * @see getCachedAttribute(const std::string&) const + * + */ + void startCaching(CacheUpdatedCallback cb); + + /** + * Stops caching. + * + * It does nothing if caching is not started. + * + * @see startCaching() + * @see startCaching(CacheUpdatedCallback) + */ + void stopCaching(); + + /** + * Returns the current cache state. + * + */ + CacheState getCacheState() const; + + /** + * Returns whether cached data is available. + * + * Cache will be available always after CacheState::READY even if current state is + * CacheState::LOST_SIGNAL. + * + * @see getCacheState() + */ + bool isCachedAvailable() const; + + /** + * Gets the cached RCSResourceAttributes data. + * + * @pre Cache should be available. + * + * @return The cached attributes. + * + * @throws BadRequestException If the precondition is not fulfilled. + * + * @see RCSResourceAttributes + * @see isCachedAvailable() + * @see startCaching() + * @see startCaching(CacheUpdatedCallback) + * + */ + RCSResourceAttributes getCachedAttributes() const; + + /** + * Gets a particular cached a ResourceAttribute Value. + * + * @pre Cache should be available. + * + * @return A requested attribute value. + * + * @throws BadRequestException If the precondition is not fulfilled. + * @throws InvalidKeyException If @a key doesn't match the key of any value. + * + * @see RCSResourceAttributes::Value + * @see isCachedAvailable() + * @see startCaching() + * @see startCaching(CacheUpdatedCallback) + * + */ + RCSResourceAttributes::Value getCachedAttribute(const std::string& key) const; + + /** + * Gets resource attributes directly from the server. + * + * This API send a get request to the resource of interest and provides + * the attributes to the caller in the RemoteAttributesReceivedCallback. + * + * @throw InvalidParameterException If cb is an empty function or null. + * + * @see RCSResourceAttributes::Value + * + * @note The callback will be invoked in an internal thread. + */ + void getRemoteAttributes(RemoteAttributesGetCallback cb); + + /** + * Sends a set request with resource attributes to the server. + * + * The SetRequest behavior depends on the server, whether updating its attributes or not. + * + * @param attributes Attributes to set + * @param cb A callback to receive the response. + * + * @throw InvalidParameterException If cb is an empty function or null. + * + * @see RCSResourceObject + * @see RCSResourceObject::SetRequestHandlerPolicy + * + * @note The callback will be invoked in an internal thread. + */ + void setRemoteAttributes(const RCSResourceAttributes& attributes, + RemoteAttributesSetCallback cb); + + /** + * Returns the uri of the resource. + * + */ + std::string getUri() const; + + /** + * Returns the address of the resource . + * + */ + std::string getAddress() const; + + /** + * Returns the resource types of the resource. + * + */ + std::vector< std::string > getTypes() const; + + /** + * Returns the resource interfaces of the resource. + * + */ + std::vector< std::string > getInterfaces() const; + + private: + std::shared_ptr< PrimitiveResource > m_primitiveResource; + CacheID m_cacheId; + BrokerID m_brokerId; }; } } -#endif //RCS_RemoteResourceObject_H +#endif // RCSREMOTERESOURCEOBJECT_H diff --git a/service/resource-encapsulation/include/RCSResourceAttributes.h b/service/resource-encapsulation/include/RCSResourceAttributes.h index 9f4c98d..5ab8c92 100644 --- a/service/resource-encapsulation/include/RCSResourceAttributes.h +++ b/service/resource-encapsulation/include/RCSResourceAttributes.h @@ -18,6 +18,11 @@ // //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +/** + * @file + * + * This file contains the "RCSResourceAttributes" class & its helper classes + */ #ifndef RES_ENCAPSULATION_RESOURCEATTRIBUTES_H #define RES_ENCAPSULATION_RESOURCEATTRIBUTES_H @@ -38,34 +43,11 @@ #include #include -/** - * @file - * - * This file contains the "RCSResourceAttributes" class & its helper classes - */ + namespace OIC { namespace Service { - /** - * Thrown when getting value with wrong template parameter. - */ - class BadGetException: public RCSException - { - public: - BadGetException(const std::string& what) : RCSException{ what } {} - BadGetException(std::string&& what) : RCSException{ std::move(what) } {} - }; - - /** - * Thrown when a key is invalid. - */ - class InvalidKeyException: public RCSException - { - public: - InvalidKeyException(const std::string& what) : RCSException{ what } {} - InvalidKeyException(std::string&& what) : RCSException{ std::move(what) } {} - }; /** * RCSResourceAttributes represents the attributes for a resource. diff --git a/service/resource-encapsulation/src/common/primitiveResource/src/RCSException.cpp b/service/resource-encapsulation/src/common/primitiveResource/src/RCSException.cpp index 64eadfe..02e8dce 100644 --- a/service/resource-encapsulation/src/common/primitiveResource/src/RCSException.cpp +++ b/service/resource-encapsulation/src/common/primitiveResource/src/RCSException.cpp @@ -41,6 +41,10 @@ namespace OIC { } + RCSException::~RCSException() noexcept + { + } + const char* RCSException::what() const noexcept { return m_what.c_str(); @@ -63,5 +67,48 @@ namespace OIC return OC::OCException::reason(m_reason); } + + BadRequestException::BadRequestException(const std::string& what) : + RCSException{ what } + { + } + + BadRequestException::BadRequestException(std::string&& what) : + RCSException{ std::move(what) } + { + } + + + InvalidParameterException::InvalidParameterException(const std::string& what) : + RCSException{ what } + { + } + + InvalidParameterException::InvalidParameterException(std::string&& what) : + RCSException{ std::move(what) } + { + } + + + BadGetException::BadGetException(const std::string& what) : + RCSException{ what } + { + } + + BadGetException::BadGetException(std::string&& what) : + RCSException{ std::move(what) } + { + } + + + InvalidKeyException::InvalidKeyException(const std::string& what) : + RCSException{ what } + { + } + + InvalidKeyException::InvalidKeyException(std::string&& what) : + RCSException{ std::move(what) } + { + } } } diff --git a/service/resource-encapsulation/src/common/primitiveResource/src/RCSResourceAttributes.cpp b/service/resource-encapsulation/src/common/primitiveResource/src/RCSResourceAttributes.cpp index 072087c..99de4a6 100644 --- a/service/resource-encapsulation/src/common/primitiveResource/src/RCSResourceAttributes.cpp +++ b/service/resource-encapsulation/src/common/primitiveResource/src/RCSResourceAttributes.cpp @@ -294,34 +294,40 @@ namespace OIC m_data.swap(rhs.m_data); } - auto RCSResourceAttributes::KeyValuePair::KeyVisitor::operator() (iterator* iter) const - -> result_type { + auto RCSResourceAttributes::KeyValuePair::KeyVisitor::operator()( + iterator* iter) const -> result_type + { return iter->m_cur->first; } - auto RCSResourceAttributes::KeyValuePair::KeyVisitor::operator() (const_iterator* iter) const - -> result_type { + auto RCSResourceAttributes::KeyValuePair::KeyVisitor::operator()( + const_iterator* iter) const -> result_type + { return iter->m_cur->first; } auto RCSResourceAttributes::KeyValuePair::ValueVisitor::operator() (iterator* iter) - -> result_type { + -> result_type + { return iter->m_cur->second; } - auto RCSResourceAttributes::KeyValuePair::ValueVisitor::operator() (const_iterator* iter) - -> result_type { + auto RCSResourceAttributes::KeyValuePair::ValueVisitor::operator() (const_iterator*) + -> result_type + { // should not reach here. throw BadGetException(""); } - auto RCSResourceAttributes::KeyValuePair::ConstValueVisitor::operator() (iterator*iter) const - -> result_type { + auto RCSResourceAttributes::KeyValuePair::ConstValueVisitor::operator()( + iterator*iter) const -> result_type + { return iter->m_cur->second; } - auto RCSResourceAttributes::KeyValuePair::ConstValueVisitor::operator() (const_iterator* iter) - const -> result_type { + auto RCSResourceAttributes::KeyValuePair::ConstValueVisitor::operator()( + const_iterator* iter) const -> result_type + { return iter->m_cur->second; } diff --git a/service/resource-encapsulation/src/common/primitiveResource/unittests/ResourceAttributesTest.cpp b/service/resource-encapsulation/src/common/primitiveResource/unittests/ResourceAttributesTest.cpp index efb7250..e60d242 100644 --- a/service/resource-encapsulation/src/common/primitiveResource/unittests/ResourceAttributesTest.cpp +++ b/service/resource-encapsulation/src/common/primitiveResource/unittests/ResourceAttributesTest.cpp @@ -260,7 +260,7 @@ TEST(ResourceAttributesValueTest, DifferentValuesAreNotEqual) TEST(ResourceAttributesValueTest, ValuesCanBeSwapped) { - constexpr int i { 1 }; + constexpr int i { 0 }; constexpr char str[]{ "abc" }; RCSResourceAttributes::Value intValue { i }; @@ -274,7 +274,7 @@ TEST(ResourceAttributesValueTest, ValuesCanBeSwapped) TEST(ResourceAttributesTypeTest, TypeIdMatchesTypeOfValue) { - RCSResourceAttributes::Value intValue { 1 }; + RCSResourceAttributes::Value intValue { 0 }; ASSERT_EQ(intValue.getType().getId(), RCSResourceAttributes::TypeId::INT); } diff --git a/service/resource-encapsulation/src/common/utils/include/ScopeLogger.h b/service/resource-encapsulation/src/common/utils/include/ScopeLogger.h new file mode 100644 index 0000000..018e538 --- /dev/null +++ b/service/resource-encapsulation/src/common/utils/include/ScopeLogger.h @@ -0,0 +1,91 @@ +//****************************************************************** +// +// Copyright 2015 Samsung Electronics All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#ifndef COMMON_UTILS_SCOPELOGGER_H +#define COMMON_UTILS_SCOPELOGGER_H + +#include "logger.h" + +#ifdef TB_LOG +#include + +namespace OIC +{ + namespace Service + { + namespace Logging + { + + class ScopeLogger + { + public: + ScopeLogger(LogLevel level, const char* tag, const char* scopeName) : + m_level{ level }, + m_tag{ tag }, + m_scopeName{ scopeName } + { + static constexpr char DEFAULT_ENTER_STR[]{ "IN" }; + + OC_LOG_V(m_level, m_tag, "%s %s", m_scopeName, DEFAULT_ENTER_STR); + } + + ~ScopeLogger() + { + static constexpr char DEFAULT_EXIT_STR[]{ "OUT" }; + + if (std::uncaught_exception()) + { + OC_LOG_V(m_level, m_tag, "%s %s by stack unwinding (uncaught exception)", + m_scopeName, DEFAULT_EXIT_STR); + } + else + { + OC_LOG_V(m_level, m_tag, "%s %s", m_scopeName, DEFAULT_EXIT_STR); + } + } + + ScopeLogger(const ScopeLogger&) = delete; + ScopeLogger(ScopeLogger&&) = delete; + + ScopeLogger& operator=(const ScopeLogger&) = delete; + ScopeLogger& operator=(ScopeLogger&&) = delete; + + private: + const LogLevel m_level; + const char* m_tag; + const char* m_scopeName; + }; + } + + } +} + +#define SCOPE_LOG(level, tag, scopeName) \ + Logging::ScopeLogger rcsScopeLogger__((level), (tag), (scopeName)) + +#define SCOPE_LOG_F(level, tag) SCOPE_LOG((level), (tag), __func__) + +#else +#define SCOPE_LOG_F(level, tag) +#define SCOPE_LOG(level, tag, scopeName) +#endif + + +#endif // COMMON_UTILS_SCOPELOGGER_H diff --git a/service/resource-encapsulation/src/resourceClient/RCSDiscoveryManager.cpp b/service/resource-encapsulation/src/resourceClient/RCSDiscoveryManager.cpp index 986ae2b..ef38e12 100644 --- a/service/resource-encapsulation/src/resourceClient/RCSDiscoveryManager.cpp +++ b/service/resource-encapsulation/src/resourceClient/RCSDiscoveryManager.cpp @@ -19,31 +19,30 @@ //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #include "RCSDiscoveryManager.h" + +#include "RCSRemoteResourceObject.h" #include "PrimitiveResource.h" -#include "logger.h" -#define CLIENT_W_TAG PCF("RCSDiscoveryManager") +#include "ScopeLogger.h" + +#define TAG PCF("RCSDiscoveryManager") using namespace OIC::Service; namespace { - void findCallback(std::shared_ptr primitiveResource, - RCSDiscoveryManager::OnResourceDiscoveredCallback OnResourceDiscovered ) + void findCallback(std::shared_ptr< PrimitiveResource > primitiveResource, + RCSDiscoveryManager::ResourceDiscoveredCallback cb) { - OC_LOG(DEBUG, CLIENT_W_TAG, "findCallback entry"); - if (nullptr == primitiveResource) + SCOPE_LOG_F(DEBUG, TAG); + + if (!primitiveResource) { - OC_LOG(ERROR, CLIENT_W_TAG, "findCallback::primitiveResource NULL Parameter"); - return ; + OC_LOG(ERROR, TAG, "findCallback : primitiveResource is null."); + return; } - std::shared_ptr< RCSRemoteResourceObject> primitiveClientResource = - std::shared_ptr< RCSRemoteResourceObject>(new RCSRemoteResourceObject(primitiveResource)); - - OnResourceDiscovered(primitiveClientResource); //passing PrimitiveClientResource to application - - OC_LOG(DEBUG, CLIENT_W_TAG, "findcb exit"); + cb(std::make_shared< RCSRemoteResourceObject >(primitiveResource)); } } @@ -51,44 +50,31 @@ namespace OIC { namespace Service { - RCSDiscoveryManager *RCSDiscoveryManager:: getInstance() + RCSDiscoveryManager* RCSDiscoveryManager::getInstance() { - OC_LOG(DEBUG, CLIENT_W_TAG, "RCSDiscoveryManager:: getInstance entry"); - static RCSDiscoveryManager *s_instance; - static std::mutex s_mutex; - if (!s_instance) - { - std::lock_guard lock(s_mutex); - if (!s_instance) - { - s_instance = new RCSDiscoveryManager(); - } - } - OC_LOG(DEBUG, CLIENT_W_TAG, "RCSDiscoveryManager:: getInstance exit"); - return s_instance; + static RCSDiscoveryManager instance; + return &instance; } - void RCSDiscoveryManager::discoverResource(const RCSAddress &address, - const std::string &resourceURI, - OnResourceDiscoveredCallback cb) + void RCSDiscoveryManager::discoverResource(const RCSAddress& address, + const std::string& resourceURI, ResourceDiscoveredCallback cb) { + SCOPE_LOG_F(DEBUG, TAG); - OC_LOG(DEBUG, CLIENT_W_TAG, "RCSDiscoveryManager::discoverResource entry"); - if ( resourceURI.empty() ) + if (resourceURI.empty()) { - OC_LOG(ERROR, CLIENT_W_TAG, "discoverResource NULL resourceURI"); - throw InvalidParameterException { "discoverResource NULL resourceURI'" }; + OC_LOG(ERROR, TAG, "discoverResource NULL resourceURI"); + throw InvalidParameterException{ "discoverResource NULL resourceURI'" }; } - else if ( !cb ) + + if (!cb) { - OC_LOG(ERROR, CLIENT_W_TAG, "discoverResource NULL Callback"); - throw InvalidParameterException { "discoverResource NULL Callback'" }; + OC_LOG(ERROR, TAG, "discoverResource NULL Callback"); + throw InvalidParameterException{ "discoverResource NULL Callback'" }; } - OIC::Service::discoverResource(address, resourceURI, std::bind(findCallback, - std::placeholders::_1, - cb)); - OC_LOG(DEBUG, CLIENT_W_TAG, "RCSDiscoveryManager::discoverResource exit"); + OIC::Service::discoverResource(address, resourceURI, + std::bind(findCallback, std::placeholders::_1, std::move(cb))); } } } diff --git a/service/resource-encapsulation/src/resourceClient/RCSRemoteResourceObject.cpp b/service/resource-encapsulation/src/resourceClient/RCSRemoteResourceObject.cpp index 2036d1b..369ef51 100644 --- a/service/resource-encapsulation/src/resourceClient/RCSRemoteResourceObject.cpp +++ b/service/resource-encapsulation/src/resourceClient/RCSRemoteResourceObject.cpp @@ -19,356 +19,275 @@ //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #include "RCSRemoteResourceObject.h" + #include "ResourceBroker.h" #include "ResourceCacheManager.h" -#define CLIENT_W_TAG PCF("RCSRemoteResourceObject") +#include "ScopeLogger.h" -using namespace OIC::Service; +#define TAG PCF("RCSRemoteResourceObject") namespace { - ResourceState getResourceStateFromBrokerState(BROKER_STATE state) - { + using namespace OIC::Service; - OC_LOG(DEBUG, CLIENT_W_TAG, "getResourceStateFromBrokerState entry"); + ResourceState convertBrokerState(BROKER_STATE state) + { + SCOPE_LOG_F(DEBUG, TAG); - if (state == BROKER_STATE::ALIVE) - { - return ResourceState::ALIVE; - } - else if (state == BROKER_STATE::REQUESTED) - { - return ResourceState::REQUESTED; - } - else if (state == BROKER_STATE::LOST_SIGNAL) + switch (state) { - return ResourceState::LOST_SIGNAL; - } - else if (state == BROKER_STATE::DESTROYED) - { - return ResourceState::DESTROYED; - } - else if (state == BROKER_STATE::NONE) - { - return ResourceState::NOT_MONITORING; + case BROKER_STATE::ALIVE: + return ResourceState::ALIVE; + + case BROKER_STATE::REQUESTED: + return ResourceState::REQUESTED; + + case BROKER_STATE::LOST_SIGNAL: + return ResourceState::LOST_SIGNAL; + + case BROKER_STATE::DESTROYED: + return ResourceState::DESTROYED; + + case BROKER_STATE::NONE: + return ResourceState::NONE; } - OC_LOG(ERROR, CLIENT_W_TAG, "getResourceStateFromBrokerState ERROR"); - //Default return value - return ResourceState::NOT_MONITORING; + return ResourceState::NONE; } - CacheState getCacheState(CACHE_STATE state) + CacheState convertCacheState(CACHE_STATE state) { + SCOPE_LOG_F(DEBUG, TAG); - OC_LOG(DEBUG, CLIENT_W_TAG, "getCacheState (from CACHE_STATE) entry"); - - if (state == CACHE_STATE::READY) - { - return CacheState::READY; - } - else if (state == CACHE_STATE::READY_YET) - { - return CacheState::READY_YET; - } - else if (state == CACHE_STATE::LOST_SIGNAL) - { - return CacheState::LOST_SIGNAL; - } - else if (state == CACHE_STATE::DESTROYED) - { - return CacheState::DESTROYED; - } - else if (state == CACHE_STATE::UPDATING) - { - return CacheState::UPDATING; - } - else if (state == CACHE_STATE::NONE) + switch (state) { - return CacheState::NONE; + case CACHE_STATE::READY: + return CacheState::READY; + + case CACHE_STATE::READY_YET: + case CACHE_STATE::UPDATING: + return CacheState::UNREADY; + + case CACHE_STATE::LOST_SIGNAL: + return CacheState::LOST_SIGNAL; + + case CACHE_STATE::DESTROYED: + case CACHE_STATE::NONE: + return CacheState::NONE; } - OC_LOG(ERROR, CLIENT_W_TAG, "getCacheState (from CACHE_STATE) ERROR"); - //Default return value return CacheState::NONE; } OCStackResult hostingCallback(BROKER_STATE state, - RCSRemoteResourceObject::ResourceStateChangedCallback onResourceStateChanged) + RCSRemoteResourceObject::StateChangedCallback onResourceStateChanged) { - OC_LOG(DEBUG, CLIENT_W_TAG, "hostingCallback entry"); + SCOPE_LOG_F(DEBUG, TAG); - ResourceState resourceState = getResourceStateFromBrokerState(state); - onResourceStateChanged(resourceState); //passing ResourceState to application - - OC_LOG(DEBUG, CLIENT_W_TAG, "hostingCallback exit"); + onResourceStateChanged(convertBrokerState(state)); return OC_STACK_OK; } - OCStackResult cachingCallback(std::shared_ptr resource, - const RCSResourceAttributes &data, - RCSRemoteResourceObject::CacheUpdatedCallback onCacheUpdated) + OCStackResult cachingCallback(std::shared_ptr< PrimitiveResource >, + const RCSResourceAttributes& data, + RCSRemoteResourceObject::CacheUpdatedCallback onCacheUpdated) { - OC_LOG(DEBUG, CLIENT_W_TAG, "cachingCallback entry"); - - onCacheUpdated(data); //passing ResourceAttributes to application + SCOPE_LOG_F(DEBUG, TAG); - OC_LOG(DEBUG, CLIENT_W_TAG, "cachingCallback exit"); + onCacheUpdated(data); return OC_STACK_OK; } - void setCallback(const HeaderOptions &header, const ResponseStatement &response, int n, - RCSRemoteResourceObject::RemoteAttributesSetCallback onRemoteAttributesSet) + void setCallback(const HeaderOptions&, const ResponseStatement& response, int, + RCSRemoteResourceObject::RemoteAttributesSetCallback onRemoteAttributesSet) { - OC_LOG(DEBUG, CLIENT_W_TAG, "setCallback entry"); - - const RCSResourceAttributes &attributes = response.getAttributes(); - onRemoteAttributesSet(attributes); //passing ResourceAttributes to application + SCOPE_LOG_F(DEBUG, TAG); - OC_LOG(DEBUG, CLIENT_W_TAG, "setCallback exit"); + onRemoteAttributesSet(response.getAttributes()); } - void getCallback(const HeaderOptions &headerOption, const ResponseStatement &response, int n, - RCSRemoteResourceObject::RemoteAttributesReceivedCallback onRemoteAttributesReceived) + void getCallback(const HeaderOptions&, const ResponseStatement& response, int, + RCSRemoteResourceObject::RemoteAttributesGetCallback onRemoteAttributesReceived) { - OC_LOG(DEBUG, CLIENT_W_TAG, "getCallback entry"); + SCOPE_LOG_F(DEBUG, TAG); - const RCSResourceAttributes &attributes = response.getAttributes(); - onRemoteAttributesReceived(attributes); //passing ResourceAttributes to application - - OC_LOG(DEBUG, CLIENT_W_TAG, "getCallback exit"); + onRemoteAttributesReceived(response.getAttributes()); } } -//******************************* RCSRemoteResourceObject ************************************* - namespace OIC { namespace Service { - RCSRemoteResourceObject:: RCSRemoteResourceObject(std::shared_ptr pResource) : - m_monitoringFlag(false), m_cachingFlag(false), m_observableFlag(pResource->isObservable()), - m_primitiveResource(pResource), m_cacheId(0), m_brokerId(0) {} + RCSRemoteResourceObject::RCSRemoteResourceObject( + std::shared_ptr< PrimitiveResource > pResource) : + m_primitiveResource{ pResource }, + m_cacheId{ }, + m_brokerId{ } + { + } + + RCSRemoteResourceObject::~RCSRemoteResourceObject() + { + SCOPE_LOG_F(DEBUG, TAG); + + stopCaching(); + stopMonitoring(); + } bool RCSRemoteResourceObject::isMonitoring() const { - return m_monitoringFlag; + return m_brokerId != 0; } bool RCSRemoteResourceObject::isCaching() const { - return m_cachingFlag; + return m_cacheId != 0; + } + + bool RCSRemoteResourceObject::isObservable() const + { + return m_primitiveResource->isObservable(); } - void RCSRemoteResourceObject::startMonitoring(ResourceStateChangedCallback cb) + void RCSRemoteResourceObject::startMonitoring(StateChangedCallback cb) { - OC_LOG(DEBUG, CLIENT_W_TAG, "RCSRemoteResourceObject::startMonitoring entry"); - if (true == m_monitoringFlag) + SCOPE_LOG_F(DEBUG, TAG); + + if (!cb) { - OC_LOG(DEBUG, CLIENT_W_TAG, "RCSRemoteResourceObject::startMonitoring : Already started"); + throw InvalidParameterException{ "startMonitoring : Callback is NULL" }; } - else + + if (isMonitoring()) { - try - { - BrokerID brokerId = ResourceBroker::getInstance()->hostResource(m_primitiveResource, - std::bind(hostingCallback, std::placeholders::_1, - cb)); - m_monitoringFlag = true; - m_brokerId = brokerId; - } - catch (std::exception &exception) - { - throw InvalidParameterException {exception.what()}; - } + OC_LOG(DEBUG, TAG, "startMonitoring : already started"); + throw BadRequestException{ "Monitoring already started." }; } - OC_LOG(DEBUG, CLIENT_W_TAG, "RCSRemoteResourceObject::startMonitoring exit"); + + m_brokerId = ResourceBroker::getInstance()->hostResource(m_primitiveResource, + std::bind(hostingCallback, std::placeholders::_1, std::move(cb))); } void RCSRemoteResourceObject::stopMonitoring() { - OC_LOG(DEBUG, CLIENT_W_TAG, "RCSRemoteResourceObject::stopMonitoring entry"); - if (true == m_monitoringFlag) - { - try - { - ResourceBroker::getInstance()->cancelHostResource(m_brokerId); - m_monitoringFlag = false; - } - catch (std::exception &exception) - { - OC_LOG(DEBUG, CLIENT_W_TAG, "RCSRemoteResourceObject::stopMonitoring InvalidParameterException"); - } - } - else + SCOPE_LOG_F(DEBUG, TAG); + + if (!isMonitoring()) { - OC_LOG(DEBUG, CLIENT_W_TAG, "RCSRemoteResourceObject:: stopMonitoring : already terminated"); + OC_LOG(DEBUG, TAG, "stopMonitoring : Not started"); + return; } - OC_LOG(DEBUG, CLIENT_W_TAG, "RCSRemoteResourceObject::stopMonitoring exit"); + ResourceBroker::getInstance()->cancelHostResource(m_brokerId); + m_brokerId = 0; } ResourceState RCSRemoteResourceObject::getState() const { - OC_LOG(DEBUG, CLIENT_W_TAG, " RCSRemoteResourceObject::getState entry"); - try - { - BROKER_STATE brokerState = ResourceBroker::getInstance()->getResourceState(m_primitiveResource); - OC_LOG(DEBUG, CLIENT_W_TAG, " RCSRemoteResourceObject::getState exit"); - return getResourceStateFromBrokerState(brokerState); - } - catch (std::exception &exception) + SCOPE_LOG_F(DEBUG, TAG); + + if (!isMonitoring()) { - OC_LOG(DEBUG, CLIENT_W_TAG, " RCSRemoteResourceObject::getState InvalidParameterException"); - throw BadRequestException { "[getState] Get Resource Source State from Broker Error " }; + return ResourceState::NONE; } + + return convertBrokerState( + ResourceBroker::getInstance()->getResourceState(m_primitiveResource)); } void RCSRemoteResourceObject::startCaching() { - OC_LOG(DEBUG, CLIENT_W_TAG, "RCSRemoteResourceObject::startCaching entry"); - if (true == m_cachingFlag) - { - OC_LOG(DEBUG, CLIENT_W_TAG, "RCSRemoteResourceObject::startCaching : already Started"); - } - else - { - try - { - CacheID cacheId = ResourceCacheManager::getInstance()->requestResourceCache(m_primitiveResource, - NULL, REPORT_FREQUENCY::NONE, 0); - - m_cacheId = cacheId; - m_cachingFlag = true; - OC_LOG_V(DEBUG, CLIENT_W_TAG, "RCSRemoteResourceObject::startCaching CACHE ID %d", cacheId); - } - catch (std::exception &exception) - { - OC_LOG(DEBUG, CLIENT_W_TAG, "RCSRemoteResourceObject::startCaching InvalidParameterException"); - } - } - OC_LOG(DEBUG, CLIENT_W_TAG, "RCSRemoteResourceObject::startCaching exit"); + startCaching({ }); } void RCSRemoteResourceObject::startCaching(CacheUpdatedCallback cb) { - OC_LOG(DEBUG, CLIENT_W_TAG, "RCSRemoteResourceObject::startCaching entry"); - if (!cb) + SCOPE_LOG_F(DEBUG, TAG); + + if (isCaching()) + { + OC_LOG(DEBUG, TAG, "startCaching : already Started"); + throw BadRequestException{ "Caching already started." }; + } + + if (cb) { - throw InvalidParameterException {"startCaching : Callback is NULL" }; + m_cacheId = ResourceCacheManager::getInstance()->requestResourceCache( + m_primitiveResource, + std::bind(cachingCallback, std::placeholders::_1, std::placeholders::_2, + std::move(cb)), REPORT_FREQUENCY::UPTODATE, 0); } else { - if (true == m_cachingFlag) - { - OC_LOG(DEBUG, CLIENT_W_TAG, "RemoteResourceObject::startCaching : already Started"); - } - else - { - try - { - CacheID cacheId = ResourceCacheManager::getInstance()->requestResourceCache(m_primitiveResource, - std::bind(cachingCallback, std::placeholders::_1, std::placeholders::_2, cb), - REPORT_FREQUENCY::UPTODATE, 0); - - m_cacheId = cacheId; - m_cachingFlag = true; - OC_LOG_V(DEBUG, CLIENT_W_TAG, "RemoteResourceObject::startCaching CACHE ID %d", cacheId); - } - catch (std::exception &exception) - { - throw InvalidParameterException {"startCaching : error" }; - } - } + m_cacheId = ResourceCacheManager::getInstance()->requestResourceCache( + m_primitiveResource, { }, REPORT_FREQUENCY::NONE, 0); } + + OC_LOG_V(DEBUG, TAG, "startCaching CACHE ID %d", m_cacheId); } void RCSRemoteResourceObject::stopCaching() { - OC_LOG(DEBUG, CLIENT_W_TAG, "RCSRemoteResourceObject::stopCaching entry"); + SCOPE_LOG_F(DEBUG, TAG); - if (true == m_cachingFlag) - { - try - { - ResourceCacheManager::getInstance()->cancelResourceCache(m_cacheId); - m_cachingFlag = false; - } - catch (std::exception &exception) - { - OC_LOG(DEBUG, CLIENT_W_TAG, "RCSRemoteResourceObject::stopCaching InvalidParameterException"); - } - } - else + if (!isCaching()) { - OC_LOG(DEBUG, CLIENT_W_TAG, "RCSRemoteResourceObject:: Caching already terminated"); + OC_LOG(DEBUG, TAG, "Caching already terminated"); + return; } - OC_LOG(DEBUG, CLIENT_W_TAG, "RCSRemoteResourceObject::stopCaching exit"); + ResourceCacheManager::getInstance()->cancelResourceCache(m_cacheId); + m_cacheId = 0; } - CacheState RCSRemoteResourceObject::getResourceCacheState() + CacheState RCSRemoteResourceObject::getCacheState() const { - OC_LOG(DEBUG, CLIENT_W_TAG, "RCSRemoteResourceObject::getResourceCacheState entry"); - try - { - CACHE_STATE cacheState = ResourceCacheManager::getInstance()->getResourceCacheState( - m_primitiveResource); - OC_LOG(DEBUG, CLIENT_W_TAG, "RCSRemoteResourceObject::getResourceCacheState exit"); - return getCacheState(cacheState); - } - catch (std::exception &exception) + SCOPE_LOG_F(DEBUG, TAG); + + if (!isCaching()) { - OC_LOG(DEBUG, CLIENT_W_TAG, - "RCSRemoteResourceObject::getResourceCacheState InvalidParameterException"); - throw BadRequestException { "[getResourceCacheState] Caching not started" }; + return CacheState::NONE; } + + return convertCacheState( + ResourceCacheManager::getInstance()->getResourceCacheState(m_primitiveResource)); } - void RCSRemoteResourceObject::refreshCache() + bool RCSRemoteResourceObject::isCachedAvailable() const { - OC_LOG(DEBUG, CLIENT_W_TAG, "RCSRemoteResourceObject::refreshCache entry"); - try + if (!isCaching()) { - - ResourceCacheManager::getInstance()->updateResourceCache( - m_primitiveResource); - } - catch (std::exception &exception) - { - OC_LOG(DEBUG, CLIENT_W_TAG, "RCSRemoteResourceObject::refreshCache InvalidParameterException"); + return false; } - OC_LOG(DEBUG, CLIENT_W_TAG, "RCSRemoteResourceObject::refreshCache exit"); + + return ResourceCacheManager::getInstance()->isCachedData(m_cacheId); } - RCSResourceAttributes RCSRemoteResourceObject:: getCachedAttributes() const + RCSResourceAttributes RCSRemoteResourceObject::getCachedAttributes() const { - OC_LOG(DEBUG, CLIENT_W_TAG, "RCSRemoteResourceObject :: getCachedAttributes "); - try + SCOPE_LOG_F(DEBUG, TAG); + + if (!isCaching()) { - return ResourceCacheManager::getInstance()->getCachedData(m_primitiveResource); + throw BadRequestException{ "Caching not started." }; } - catch (std::exception &exception) + + if (!isCachedAvailable()) { - throw BadRequestException { "[getCachedAttributes] Caching not started" }; + throw BadRequestException{ "Cache data is not available." }; } + + return ResourceCacheManager::getInstance()->getCachedData(m_primitiveResource); } - RCSResourceAttributes::Value RCSRemoteResourceObject:: getCachedAttribute( const std::string &key) + RCSResourceAttributes::Value RCSRemoteResourceObject::getCachedAttribute( + const std::string& key) const { - OC_LOG(DEBUG, CLIENT_W_TAG, "RCSRemoteResourceObject :: getCachedAttribute entry"); - try - { - RCSResourceAttributes Cachedattributes = ResourceCacheManager::getInstance()->getCachedData( - m_primitiveResource); - return Cachedattributes[key]; - } - catch (std::exception &exception) - { - throw BadRequestException { "[getCachedAttribute] Caching not started" }; - } - OC_LOG(DEBUG, CLIENT_W_TAG, "RCSRemoteResourceObject :: getCachedAttribute exit"); + SCOPE_LOG_F(DEBUG, TAG); + + return getCachedAttributes().at(key); } std::string RCSRemoteResourceObject::getUri() const @@ -381,51 +300,43 @@ namespace OIC return m_primitiveResource->getHost(); } - std::vector < std::string > RCSRemoteResourceObject::getTypes() const + std::vector< std::string > RCSRemoteResourceObject::getTypes() const { return m_primitiveResource->getTypes(); } - std::vector < std::string > RCSRemoteResourceObject::getInterfaces() const + std::vector< std::string > RCSRemoteResourceObject::getInterfaces() const { return m_primitiveResource->getInterfaces(); } - void RCSRemoteResourceObject::getRemoteAttributes(RemoteAttributesReceivedCallback cb) + void RCSRemoteResourceObject::getRemoteAttributes(RemoteAttributesGetCallback cb) { - OC_LOG(DEBUG, CLIENT_W_TAG, "RemoteResourceObject::getRemoteAttributes entry"); + SCOPE_LOG_F(DEBUG, TAG); + if (!cb) { - throw InvalidParameterException {"getRemoteAttributes : Callback is NULL" }; + throw InvalidParameterException{ "getRemoteAttributes : Callback is empty" }; } - else - { - m_primitiveResource->requestGet(std::bind(getCallback, std::placeholders::_1, - std::placeholders::_2, std::placeholders::_3, cb)); - } - OC_LOG(DEBUG, CLIENT_W_TAG, "RemoteResourceObject::getRemoteAttributes exit"); + + m_primitiveResource->requestGet( + std::bind(getCallback, std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, std::move(cb))); } - void RCSRemoteResourceObject::setRemoteAttributes(const RCSResourceAttributes &attribute, + void RCSRemoteResourceObject::setRemoteAttributes(const RCSResourceAttributes& attribute, RemoteAttributesSetCallback cb) { - OC_LOG(DEBUG, CLIENT_W_TAG, "RemoteResourceObject::setRemoteAttributes entry"); + SCOPE_LOG_F(DEBUG, TAG); + if (!cb) { - throw InvalidParameterException {"setRemoteAttributes : Callback is NULL" }; - } - else - { - m_primitiveResource->requestSet(attribute, std::bind(setCallback, std::placeholders::_1, - std::placeholders::_2, std::placeholders::_3, cb)); + throw InvalidParameterException{ "setRemoteAttributes : Callback is empty" }; } - OC_LOG(DEBUG, CLIENT_W_TAG, "RemoteResourceObject::setRemoteAttributes exit"); - } - - bool RCSRemoteResourceObject::isObservable() const - { - return m_observableFlag; + m_primitiveResource->requestSet(attribute, + std::bind(setCallback, std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, cb)); } } } diff --git a/service/resource-encapsulation/unittests/ResourceClientTest.cpp b/service/resource-encapsulation/unittests/ResourceClientTest.cpp new file mode 100644 index 0000000..9486e90 --- /dev/null +++ b/service/resource-encapsulation/unittests/ResourceClientTest.cpp @@ -0,0 +1,346 @@ +//****************************************************************** +// +// Copyright 2015 Samsung Electronics All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#include "UnitTestHelper.h" +#include "RCSRemoteResourceObject.h" +#include "RCSDiscoveryManager.h" +#include "RCSResourceObject.h" +#include "PrimitiveResource.h" + +#include + +using namespace OIC::Service; +using namespace OC; + +constexpr char RESOURCEURI[]{ "/a/TemperatureSensor" }; +constexpr char RESOURCETYPE[]{ "Resource.Hosting" }; +constexpr char RESOURCEINTERFACE[]{ "oic.if.baseline" }; + +constexpr char ATTR_KEY[]{ "Temperature" }; +constexpr int ATTR_VALUE{ 0 }; + +constexpr int DEFAULT_WAITING_TIME_IN_MILLIS = 3000; + +void getRemoteAttributesCallback(const RCSResourceAttributes&) {} +void setRemoteAttributesCallback(const RCSResourceAttributes&) {} +void resourceStateChanged(ResourceState) { } +void cacheUpdatedCallback(const RCSResourceAttributes&) {} + +class RemoteResourceObjectTest: public TestWithMock +{ +public: + RCSResourceObject::Ptr server; + RCSRemoteResourceObject::Ptr object; + std::shared_ptr< bool > finished; + +public: + void Proceed() + { + cond.notify_all(); + } + + void Wait(int waitingTime = DEFAULT_WAITING_TIME_IN_MILLIS) + { + std::unique_lock< std::mutex > lock{ mutex }; + cond.wait_for(lock, std::chrono::milliseconds{ waitingTime }); + } + +protected: + void SetUp() + { + TestWithMock::SetUp(); + + finished = std::make_shared< bool >(false); + + CreateResource(); + + WaitUntilDiscovered(); + } + + void TearDown() + { + TestWithMock::TearDown(); + + // This method is to make sure objects disposed. + WaitForPtrBeingUnique(); + + *finished = true; + } + +private: + void CreateResource() + { + server = RCSResourceObject::Builder(RESOURCEURI, RESOURCETYPE, RESOURCEINTERFACE).build(); + server->setAttribute(ATTR_KEY, ATTR_VALUE); + } + + bool checkObject() + { + std::lock_guard lock{ mutexForObject }; + return object == nullptr; + } + + void WaitUntilDiscovered() + { + while (checkObject()) + { + RCSDiscoveryManager::getInstance()->discoverResource(RCSAddress::multicast(), + "/oic/res?rt=Resource.Hosting", std::bind(resourceDiscovered, this, finished, + std::placeholders::_1)); + + Wait(1000); + } + } + + void WaitForPtrBeingUnique() + { + while((object && !object.unique()) || (server && !server.unique())) + { + std::this_thread::sleep_for(std::chrono::milliseconds{ 100 }); + } + } + + // This callback is to protect crash from crashes caused by delayed callbacks + static void resourceDiscovered(RemoteResourceObjectTest* test, + std::shared_ptr< bool > finished, RCSRemoteResourceObject::Ptr resourceObject) + { + if (*finished) return; + + { + std::lock_guard< std::mutex > lock{ test->mutexForObject }; + + if (test->object) return; + + test->object = resourceObject; + } + + test->Proceed(); + } + +private: + std::condition_variable cond; + std::mutex mutex; + std::mutex mutexForObject; +}; + +TEST_F(RemoteResourceObjectTest, GetRemoteAttributesDoesNotAllowEmptyFunction) +{ + ASSERT_THROW(object->getRemoteAttributes({ }), InvalidParameterException); +} + +TEST_F(RemoteResourceObjectTest, GetRemoteAttributesGetsAttributesOfServer) +{ + mocks.ExpectCallFunc(getRemoteAttributesCallback).Match( + [this](const RCSResourceAttributes& attrs) + { + RCSResourceObject::LockGuard lock{ server }; + return attrs == server->getAttributes(); + } + ).Do([this](const RCSResourceAttributes&){ Proceed(); }); + + object->getRemoteAttributes(getRemoteAttributesCallback); + + Wait(); +} + +TEST_F(RemoteResourceObjectTest, SetRemoteAttributesDoesNotAllowEmptyFunction) +{ + ASSERT_THROW(object->setRemoteAttributes({ }, { }), InvalidParameterException); +} + +TEST_F(RemoteResourceObjectTest, SetRemoteAttributesSetsAttributesOfServer) +{ + constexpr int newValue = ATTR_VALUE + 1; + RCSResourceAttributes newAttrs; + newAttrs[ATTR_KEY] = newValue; + + mocks.ExpectCallFunc(setRemoteAttributesCallback). + Do([this](const RCSResourceAttributes&){ Proceed(); }); + + object->setRemoteAttributes(newAttrs, setRemoteAttributesCallback); + Wait(); + + ASSERT_EQ(newValue, server->getAttributeValue(ATTR_KEY)); +} + +TEST_F(RemoteResourceObjectTest, MonitoringIsNotStartedByDefault) +{ + ASSERT_FALSE(object->isMonitoring()); +} + +TEST_F(RemoteResourceObjectTest, StartMonitoringThrowsIfFunctionIsEmpty) +{ + ASSERT_THROW(object->startMonitoring({ }), InvalidParameterException); +} + +TEST_F(RemoteResourceObjectTest, IsMonitoringReturnsTrueAfterStartMonitoring) +{ + object->startMonitoring(resourceStateChanged); + + ASSERT_TRUE(object->isMonitoring()); +} + +TEST_F(RemoteResourceObjectTest, StartMonitoringThrowsIfTryingToStartAgain) +{ + object->startMonitoring(resourceStateChanged); + + ASSERT_THROW(object->startMonitoring(resourceStateChanged), BadRequestException); +} + +TEST_F(RemoteResourceObjectTest, DefaultStateIsNone) +{ + ASSERT_EQ(ResourceState::NONE, object->getState()); +} + +TEST_F(RemoteResourceObjectTest, CachingIsNotStartedByDefault) +{ + ASSERT_FALSE(object->isCaching()); +} + +TEST_F(RemoteResourceObjectTest, IsCachingReturnsTrueAfterStartCaching) +{ + object->startCaching(cacheUpdatedCallback); + + ASSERT_TRUE(object->isCaching()); +} + +TEST_F(RemoteResourceObjectTest, StartCachingThrowsIfTryingToStartAgain) +{ + object->startCaching(cacheUpdatedCallback); + + ASSERT_THROW(object->startCaching(), BadRequestException); +} + +TEST_F(RemoteResourceObjectTest, DefaultCacheStateIsNone) +{ + ASSERT_EQ(CacheState::NONE, object->getCacheState()); +} + +TEST_F(RemoteResourceObjectTest, CacheStateIsUnreadyAfterStartCaching) +{ + object->startCaching(); + + ASSERT_EQ(CacheState::UNREADY, object->getCacheState()); +} + +TEST_F(RemoteResourceObjectTest, CacheStateIsReadyAfterCacheUpdated) +{ + mocks.ExpectCallFunc(cacheUpdatedCallback). + Do([this](const RCSResourceAttributes&){ Proceed(); }); + + object->startCaching(cacheUpdatedCallback); + Wait(); + + ASSERT_EQ(CacheState::READY, object->getCacheState()); +} + +TEST_F(RemoteResourceObjectTest, IsCachedAvailableReturnsTrueWhenCacheIsReady) +{ + mocks.ExpectCallFunc(cacheUpdatedCallback). + Do([this](const RCSResourceAttributes&){ Proceed(); }); + + object->startCaching(cacheUpdatedCallback); + Wait(); + + ASSERT_TRUE(object->isCachedAvailable()); +} + +TEST_F(RemoteResourceObjectTest, DISABLED_CacheUpdatedCallbackBeCalledWheneverCacheUpdated) +{ + mocks.OnCallFunc(cacheUpdatedCallback). + Do([this](const RCSResourceAttributes&){ Proceed(); }); + object->startCaching(cacheUpdatedCallback); + Wait(); + + mocks.ExpectCallFunc(cacheUpdatedCallback). + Do([this](const RCSResourceAttributes&){ Proceed(); }); + + server->setAttribute(ATTR_KEY, ATTR_VALUE + 1); + + Wait(); +} + +TEST_F(RemoteResourceObjectTest, DISABLED_CacheUpdatedCallbackBeCalledWithUpdatedAttributes) +{ + constexpr int newValue = ATTR_VALUE + 1; + + mocks.OnCallFunc(cacheUpdatedCallback). + Do([this](const RCSResourceAttributes&){ Proceed(); }); + object->startCaching(cacheUpdatedCallback); + Wait(); + + mocks.ExpectCallFunc(cacheUpdatedCallback). + Match([this](const RCSResourceAttributes& attrs){ + return attrs.at(ATTR_KEY) == newValue; + }). + Do([this](const RCSResourceAttributes&){ Proceed(); }); + + server->setAttribute(ATTR_KEY, newValue); + + Wait(); +} + +TEST_F(RemoteResourceObjectTest, GetCachedAttributesThrowsIfCachingIsNotStarted) +{ + ASSERT_THROW(object->getCachedAttributes(), BadRequestException); +} + +TEST_F(RemoteResourceObjectTest, CachedAttributesHasSameAttributesWithServer) +{ + mocks.OnCallFunc(cacheUpdatedCallback). + Do([this](const RCSResourceAttributes&){ Proceed(); }); + object->startCaching(cacheUpdatedCallback); + Wait(); + + RCSResourceObject::LockGuard lock{ server }; + + ASSERT_EQ(object->getCachedAttributes(), server->getAttributes()); +} + +TEST_F(RemoteResourceObjectTest, GetCachedAttributeThrowsIfCachingIsNotStarted) +{ + ASSERT_THROW(object->getCachedAttribute(ATTR_KEY), BadRequestException); +} + +TEST_F(RemoteResourceObjectTest, GetCachedAttributeThrowsIfKeyIsInvalid) +{ + mocks.OnCallFunc(cacheUpdatedCallback). + Do([this](const RCSResourceAttributes&){ Proceed(); }); + object->startCaching(cacheUpdatedCallback); + Wait(); + + ASSERT_THROW(object->getCachedAttribute(""), InvalidKeyException); +} + +TEST_F(RemoteResourceObjectTest, HasSameUriWithServer) +{ + EXPECT_EQ(RESOURCEURI, object->getUri()); +} + +TEST_F(RemoteResourceObjectTest, HasSameTypeWithServer) +{ + EXPECT_EQ(RESOURCETYPE, object->getTypes()[0]); +} + +TEST_F(RemoteResourceObjectTest, HasSameInterfaceWithServer) +{ + EXPECT_EQ(RESOURCEINTERFACE, object->getInterfaces()[0]); +} + diff --git a/service/resource-encapsulation/unittests/ResourceClient_Test.cpp b/service/resource-encapsulation/unittests/ResourceClient_Test.cpp deleted file mode 100644 index 653bdd3..0000000 --- a/service/resource-encapsulation/unittests/ResourceClient_Test.cpp +++ /dev/null @@ -1,381 +0,0 @@ -//****************************************************************** -// -// Copyright 2015 Samsung Electronics All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -#define private public -#include -#include -#include "RCSDiscoveryManager.h" -#include "RCSRemoteResourceObject.h" -#include "RCSResourceObject.h" -#include "OCPlatform.h" -#include "RCSAddress.h" - -#define RESOURCEURI "/a/TemperatureSensor" -#define RESOURCETYPE "Resource.Hosting" -#define RESOURCEINTERFACE "oic.if.baseline" - -using namespace OIC::Service; -using namespace OC; - -bool cbresult = false; -std::string uri = "/oic/res?rt=Resource.Hosting"; -std::shared_ptr object; -RCSDiscoveryManager*manager = RCSDiscoveryManager::getInstance(); -ResourceState receivedResourceState; -RCSResourceAttributes receivedResourceAttributes; -RCSResourceObject::Ptr server; - -void createResource() -{ - server = RCSResourceObject::Builder(RESOURCEURI, RESOURCETYPE, - RESOURCEINTERFACE).setDiscoverable(true).setObservable(true).build(); - std::cout << "Resource created successfully " << std::endl; - server->setAttribute("Temperature", 0); - PlatformConfig config - { - OC::ServiceType::InProc, ModeType::Client, "0.0.0.0", 0, OC::QualityOfService::LowQos - }; - OCPlatform::Configure(config); -} - -void destroyResource() -{ - server = NULL; -} - -//Callbacks -void onRemoteAttrReceived(const RCSResourceAttributes &attributes) -{ - cbresult = true; - receivedResourceAttributes = attributes; -} - -void onResourceDiscoveredCallback(std::shared_ptr receivedObject) -{ - std::cout << "Resource discovered" << std::endl; - object = receivedObject; - std::cout << object->getUri() << std::endl; - std::cout << "Resource discovered exited" << std::endl; - EXPECT_TRUE(object != NULL); -} - -void onResourceStateChanged(ResourceState state) -{ - receivedResourceState = state; -} - -void onCacheUpdated(const RCSResourceAttributes attribute) -{ - receivedResourceAttributes = attribute; -} - -void OnRemoteAttributesSetCallback(const RCSResourceAttributes &attributes) -{ - cbresult = true; -} - -//Send valid call to discover resource -TEST(ResourceClientTest, testDiscoverResourcePass) -{ - createResource(); - RCSDiscoveryManager *instance = RCSDiscoveryManager::getInstance(); - cbresult = false; - RCSAddress rcsAddress = RCSAddress::multicast(); - instance->discoverResource(rcsAddress, uri , &onResourceDiscoveredCallback); - sleep(2); - EXPECT_TRUE(object != NULL); - destroyResource(); -} - -//Get remote attributes when callback is valid -TEST(ResourceClientTest, testGetRemoteAttributesPass) -{ - createResource(); - sleep(2); - cbresult = false; - object->getRemoteAttributes(&onRemoteAttrReceived); - sleep(2); - - EXPECT_TRUE(cbresult); - destroyResource(); -} - -//Set remote attributes when callback is valid -TEST(ResourceClientTest, testSetRemoteAttributesPass) -{ - createResource(); - sleep(2); - - cbresult = false; - object->getRemoteAttributes(&onRemoteAttrReceived); - sleep(2); - RCSResourceAttributes::const_iterator iter = receivedResourceAttributes.begin(); - for (unsigned int i = 0; i < receivedResourceAttributes.size(); ++i) - { - if ( iter->key() == "Temperature") - { - std::cout << "It is there" << std::endl; - receivedResourceAttributes["Temperature"] = 100; - object->setRemoteAttributes(receivedResourceAttributes, &OnRemoteAttributesSetCallback); - } - ++iter; - } - sleep(2); - EXPECT_TRUE(cbresult); - destroyResource(); -} - -//Check value of isMonitoring -TEST(ResourceClientTest, testIsMonitoring) -{ - createResource(); - RCSAddress rcsAddress = RCSAddress::multicast(); - manager->RCSDiscoveryManager::discoverResource(rcsAddress, uri , &onResourceDiscoveredCallback); - sleep(1); - destroyResource(); - EXPECT_FALSE(object->isMonitoring()); -} - -//Check value of isCaching -TEST(ResourceClientTest, testIsCaching) -{ - createResource(); - destroyResource(); - EXPECT_FALSE(object->isCaching()); -} - -TEST(ResourceClientTest, testIsObservable) -{ - createResource(); - destroyResource(); - EXPECT_TRUE(object->isObservable()); -} - -//Check value of startMonitoring for NULL callback -TEST(ResourceClientTest, testStartMonitoringFail) -{ - createResource(); - object->m_monitoringFlag = false; - object->startMonitoring(NULL); - EXPECT_TRUE(object->m_monitoringFlag); - object->stopMonitoring(); - destroyResource(); -} - -//Check value of startMonitoring for valid callback -TEST(ResourceClientTest, testStartMonitoringPass) -{ - createResource(); - object->startMonitoring(&onResourceStateChanged); - EXPECT_TRUE(object->m_monitoringFlag); - object->stopMonitoring(); - destroyResource(); -} - -//Stop Monitoring when Monitoring is true -TEST(ResourceClientTest, testStopMonitoring) -{ - createResource(); - object->startMonitoring(&onResourceStateChanged); - object->stopMonitoring(); - EXPECT_FALSE(object->m_monitoringFlag); - object->startMonitoring(&onResourceStateChanged); - destroyResource(); -} - -//Get state of resource -TEST(ResourceClientTest, testGetStatePass) -{ - createResource(); - ResourceState result = object->getState(); - EXPECT_TRUE(result >= ResourceState::NOT_MONITORING && result <= ResourceState::DESTROYED); - destroyResource(); -} - -//Cache ID is not zero -TEST(ResourceClientTest, testStartCachingPass) -{ - createResource(); - object->m_cachingFlag = false; - object->startCaching(); - EXPECT_TRUE(object->m_cachingFlag); - destroyResource(); -} - -TEST(ResourceClientTest, testStopCaching) -{ - createResource(); - object->m_cachingFlag = false; - object->startCaching(); - object->stopCaching(); - EXPECT_FALSE(object->m_cachingFlag); - destroyResource(); -} - -TEST(ResourceClientTest, testRefreshCache) -{ - createResource(); - object->m_cachingFlag = false; - object->startCaching(); - object->refreshCache(); - EXPECT_TRUE(object->getResourceCacheState() == CacheState::UPDATING); - destroyResource(); -} - -//Callback for start caching is valid -TEST(ResourceClientTest, testStartCachingCbPass) -{ - createResource(); - object->m_cachingFlag = false; - object->startCaching(&onCacheUpdated); - EXPECT_TRUE(object->m_cachingFlag); - destroyResource(); -} - -//Callback for start caching is NULL -TEST(ResourceClientTest, testStartCachingCbFail) -{ - createResource(); - object->m_cachingFlag = false; - object->startCaching(NULL); - EXPECT_TRUE(object->m_cachingFlag); - destroyResource(); -} - -//Get resource state -TEST(ResourceClientTest, testGetResourceCacheState) -{ - createResource(); - CacheState result = object->getResourceCacheState(); - EXPECT_TRUE(result >= CacheState::READY && result <= CacheState::NONE); - destroyResource(); -} - -//Get cached attributes -TEST(ResourceClientTest, testGetCachedAttributesWithoutCallback) -{ - createResource(); - RCSResourceAttributes result = object->getCachedAttributes(); - EXPECT_TRUE(result.empty()); - destroyResource(); -} - -//Check with invalid attribute value -TEST(ResourceClientTest, testGetCachedAttributeWithInvalidAttribute) -{ - createResource(); - RCSResourceAttributes::Value result = object->getCachedAttribute(""); - EXPECT_TRUE(result == nullptr); - destroyResource(); -} - -//Get remote attributes when callback is NULL -TEST(ResourceClientTest, testGetRemoteAttributesFail) -{ - createResource(); - cbresult = false; - object->getRemoteAttributes(NULL); - EXPECT_FALSE(cbresult); - destroyResource(); -} - -TEST(ResourceClientTest, testGetUri) -{ - createResource(); - std::string result = object->getUri(); - EXPECT_TRUE(!result.empty()); - destroyResource(); -} - -TEST(ResourceClientTest, testGetAddress) -{ - createResource(); - std::string result = object->getAddress(); - EXPECT_TRUE(!result.empty()); - destroyResource(); -} - -TEST(ResourceClientTest, testGetTypes) -{ - createResource(); - std::vector < std::string > result = object->getTypes(); - EXPECT_TRUE(result.size() != 0); - destroyResource(); -} - -TEST(ResourceClientTest, testGetInterfaces) -{ - createResource(); - std::vector < std::string > result = object->getInterfaces(); - EXPECT_TRUE(result.size() != 0); - destroyResource(); -} - -//Check with valid attribute value -TEST(ResourceClientTest, testGetCachedAttribute) -{ - createResource(); - RCSResourceAttributes::Value result = object->getCachedAttribute("Temperature"); - EXPECT_TRUE(result != nullptr); - destroyResource(); -} - -//Test getting instance of DiscoveryManager -TEST(ResourceClientTest, testGetInstance) -{ - createResource(); - RCSDiscoveryManager *instance = RCSDiscoveryManager::getInstance(); - EXPECT_TRUE(instance != NULL); - destroyResource(); -} - -//Send empty resource URI -TEST(ResourceClientTest, testDiscoverResourceEmptyResource) -{ - createResource(); - RCSDiscoveryManager *instance = RCSDiscoveryManager::getInstance(); - RCSAddress rcsAddress = RCSAddress::multicast(); - EXPECT_THROW(instance->discoverResource(rcsAddress, "", &onResourceDiscoveredCallback), - InvalidParameterException); - destroyResource(); -} - -//Send NULL callback -TEST(ResourceClientTest, testDiscoverResourceEmptyCallback) -{ - createResource(); - RCSDiscoveryManager *instance = RCSDiscoveryManager::getInstance(); - RCSAddress rcsAddress = RCSAddress::multicast(); - EXPECT_THROW(instance->discoverResource(rcsAddress, uri , NULL), InvalidParameterException); - destroyResource(); - object->stopMonitoring(); -} - -//Send invalid RCSResourceAttributes object to function -TEST(ResourceClientTest, testSetRemoteAttributesInvalidAttributes) -{ - createResource(); - cbresult = false; - RCSResourceAttributes attr; - //object->getRemoteAttributes(&onRemoteAttrReceived); - object->setRemoteAttributes(attr, &OnRemoteAttributesSetCallback); - EXPECT_FALSE(cbresult); - destroyResource(); -} diff --git a/service/resource-encapsulation/unittests/SConscript b/service/resource-encapsulation/unittests/SConscript index bf00ac3..72a869c 100644 --- a/service/resource-encapsulation/unittests/SConscript +++ b/service/resource-encapsulation/unittests/SConscript @@ -63,9 +63,10 @@ gtest_main = File(gtest_dir + '/lib/.libs/libgtest_main.a') ResourceClient_gtest_env.AppendUnique( CPPPATH = [ - env.get('SRC_DIR')+'/extlibs', + src_dir + '/extlibs/hippomocks-master', + src_dir + '/extlibs/gtest/gtest-1.7.0/include', '../include', - '..src/serverBuilder/include/internal', + '../src/common/utils/include', '../src/serverBuilder/include', '../src/common/primitiveResource/include', '../src/common/include/expiryTimer' @@ -77,9 +78,18 @@ if target_os not in ['windows', 'winrt']: ResourceClient_gtest_env.AppendUnique(CXXFLAGS = ['-pthread']) ResourceClient_gtest_env.AppendUnique(LIBS = ['pthread']) -ResourceClient_gtest_env.PrependUnique(CPPPATH = [env.get('SRC_DIR')+'/extlibs/hippomocks-master/HippoMocks', gtest_dir + '/include']) -ResourceClient_gtest_env.AppendUnique(LIBPATH = ['/usr/lib/jvm/jdk1.8.0_40/jre/lib/amd64/server/']) -ResourceClient_gtest_env.PrependUnique(LIBS = ['rcs_client','rcs_server', 'rcs_common', 'oc','octbstack', 'oc_logger', 'oc_logger_core', 'connectivity_abstraction', gtest, gtest_main]) +ResourceClient_gtest_env.PrependUnique(LIBS = [ + 'rcs_client', + 'rcs_server', + 'rcs_common', + 'oc', + 'octbstack', + 'oc_logger', + 'oc_logger_core', + 'connectivity_abstraction', + gtest, + gtest_main]) + ResourceClient_gtest_env.AppendUnique(LIBS = ['dl']) ###################################################################### @@ -87,7 +97,7 @@ ResourceClient_gtest_env.AppendUnique(LIBS = ['dl']) ###################################################################### ResourceClient_gtest_src = env.Glob('./*.cpp') -ResourceClient_test = ResourceClient_gtest_env.Program('ResourceClient_Test', ResourceClient_gtest_src) +ResourceClient_test = ResourceClient_gtest_env.Program('ResourceClientTest', ResourceClient_gtest_src) Alias("ResourceClient_Test", ResourceClient_test) env.AppendTarget('ResourceClient_test') -- 2.7.4