diff --git a/CHAOSFramework.xcodeproj/project.pbxproj b/CHAOSFramework.xcodeproj/project.pbxproj
index cca669e1e0d901f291e278defdd514a02f559fc8..eaba6d8081856323272f5dea51e3e4b5a59e8276 100644
--- a/CHAOSFramework.xcodeproj/project.pbxproj
+++ b/CHAOSFramework.xcodeproj/project.pbxproj
@@ -7436,7 +7436,7 @@
 				);
 				LD_RUNPATH_SEARCH_PATHS = "$(SRCROOT)/usr/local/lib";
 				LIBRARY_SEARCH_PATHS = "$(SRCROOT)/usr/local/lib";
-				MACOSX_DEPLOYMENT_TARGET = 10.10;
+				MACOSX_DEPLOYMENT_TARGET = 10.14;
 				MTL_ENABLE_DEBUG_INFO = YES;
 				OTHER_LDFLAGS = (
 					"-lchaos_metadata_service_client",
@@ -7483,7 +7483,7 @@
 				);
 				LD_RUNPATH_SEARCH_PATHS = "$(SRCROOT)/usr/local/lib";
 				LIBRARY_SEARCH_PATHS = "$(SRCROOT)/usr/local/lib";
-				MACOSX_DEPLOYMENT_TARGET = 10.10;
+				MACOSX_DEPLOYMENT_TARGET = 10.14;
 				MTL_ENABLE_DEBUG_INFO = NO;
 				OTHER_LDFLAGS = (
 					"-lchaos_metadata_service_client",
@@ -7533,7 +7533,7 @@
 				);
 				LD_RUNPATH_SEARCH_PATHS = "$(SRCROOT)/usr/local/lib";
 				LIBRARY_SEARCH_PATHS = "$(SRCROOT)/usr/local/lib";
-				MACOSX_DEPLOYMENT_TARGET = 10.10;
+				MACOSX_DEPLOYMENT_TARGET = 10.14;
 				ONLY_ACTIVE_ARCH = YES;
 				OTHER_LDFLAGS = (
 					"$(inherited)",
@@ -7579,7 +7579,7 @@
 				);
 				LD_RUNPATH_SEARCH_PATHS = "$(SRCROOT)/usr/local/lib";
 				LIBRARY_SEARCH_PATHS = "$(SRCROOT)/usr/local/lib";
-				MACOSX_DEPLOYMENT_TARGET = 10.10;
+				MACOSX_DEPLOYMENT_TARGET = 10.14;
 				OTHER_LDFLAGS = (
 					"$(inherited)",
 					"-lchaos_common",
@@ -7923,7 +7923,7 @@
 				);
 				INSTALL_PATH = "$(SRCROOT)/usr/local/lib";
 				LIBRARY_SEARCH_PATHS = "$(SRCROOT)/usr/local/lib";
-				MACOSX_DEPLOYMENT_TARGET = 10.12;
+				MACOSX_DEPLOYMENT_TARGET = 10.14;
 				MTL_ENABLE_DEBUG_INFO = YES;
 				OTHER_LDFLAGS = "-lboost_system";
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -7978,7 +7978,7 @@
 				);
 				INSTALL_PATH = "$(SRCROOT)/usr/local/lib";
 				LIBRARY_SEARCH_PATHS = "$(SRCROOT)/usr/local/lib";
-				MACOSX_DEPLOYMENT_TARGET = 10.12;
+				MACOSX_DEPLOYMENT_TARGET = 10.14;
 				MTL_ENABLE_DEBUG_INFO = NO;
 				OTHER_LDFLAGS = "-lboost_system";
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -7993,13 +7993,19 @@
 				CLANG_CXX_LIBRARY = "libc++";
 				COMPILER_INDEX_STORE_ENABLE = NO;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
+				GCC_OPTIMIZATION_LEVEL = 0;
 				GCC_PREPROCESSOR_DEFINITIONS = "";
 				HEADER_SEARCH_PATHS = (
 					.,
 					usr/local/include,
 				);
 				LIBRARY_SEARCH_PATHS = "$(SRCROOT)/usr/local/lib";
+				MACOSX_DEPLOYMENT_TARGET = 10.14;
 				ONLY_ACTIVE_ARCH = NO;
+				OTHER_CFLAGS = (
+					"-fno-stack-check",
+					"-fno-stack-protector",
+				);
 				OTHER_LDFLAGS = (
 					"-lboost_log_setup",
 					"-lboost_random",
@@ -8021,13 +8027,19 @@
 				CLANG_CXX_LIBRARY = "libc++";
 				COMPILER_INDEX_STORE_ENABLE = NO;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
+				GCC_OPTIMIZATION_LEVEL = 0;
 				GCC_PREPROCESSOR_DEFINITIONS = "";
 				HEADER_SEARCH_PATHS = (
 					.,
 					usr/local/include,
 				);
 				LIBRARY_SEARCH_PATHS = "$(SRCROOT)/usr/local/lib";
+				MACOSX_DEPLOYMENT_TARGET = 10.14;
 				ONLY_ACTIVE_ARCH = NO;
+				OTHER_CFLAGS = (
+					"-fno-stack-check",
+					"-fno-stack-protector",
+				);
 				OTHER_LDFLAGS = (
 					"-lboost_log_setup",
 					"-lboost_random",
@@ -8081,7 +8093,7 @@
 				);
 				INSTALL_PATH = "$(SRCROOT)/usr/local/lib";
 				LIBRARY_SEARCH_PATHS = "$(SRCROOT)/usr/local/lib";
-				MACOSX_DEPLOYMENT_TARGET = 10.10;
+				MACOSX_DEPLOYMENT_TARGET = 10.14;
 				ONLY_ACTIVE_ARCH = YES;
 				OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)";
 				OTHER_LDFLAGS = (
@@ -8120,7 +8132,7 @@
 				);
 				INSTALL_PATH = "$(SRCROOT)/usr/local/lib";
 				LIBRARY_SEARCH_PATHS = "$(SRCROOT)/usr/local/lib";
-				MACOSX_DEPLOYMENT_TARGET = 10.10;
+				MACOSX_DEPLOYMENT_TARGET = 10.14;
 				OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)";
 				OTHER_LDFLAGS = (
 					"$(inherited)",
@@ -8161,7 +8173,7 @@
 				);
 				INSTALL_PATH = "$(SRCROOT)/usr/local/lib";
 				LIBRARY_SEARCH_PATHS = "$(SRCROOT)/usr/local/lib";
-				MACOSX_DEPLOYMENT_TARGET = 10.10;
+				MACOSX_DEPLOYMENT_TARGET = 10.14;
 				ONLY_ACTIVE_ARCH = YES;
 				OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)";
 				OTHER_LDFLAGS = (
@@ -8196,7 +8208,7 @@
 				);
 				INSTALL_PATH = "$(SRCROOT)/usr/local/lib";
 				LIBRARY_SEARCH_PATHS = "$(SRCROOT)/usr/local/lib";
-				MACOSX_DEPLOYMENT_TARGET = 10.10;
+				MACOSX_DEPLOYMENT_TARGET = 10.14;
 				OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)";
 				OTHER_LDFLAGS = (
 					"$(inherited)",
@@ -8253,7 +8265,7 @@
 					usr/local/include,
 				);
 				LIBRARY_SEARCH_PATHS = "$(SRCROOT)/usr/local/lib";
-				MACOSX_DEPLOYMENT_TARGET = 10.12;
+				MACOSX_DEPLOYMENT_TARGET = 10.14;
 				MTL_ENABLE_DEBUG_INFO = YES;
 				OTHER_LDFLAGS = (
 					"-lchaos_common",
@@ -8307,7 +8319,7 @@
 					usr/local/include,
 				);
 				LIBRARY_SEARCH_PATHS = "$(SRCROOT)/usr/local/lib";
-				MACOSX_DEPLOYMENT_TARGET = 10.12;
+				MACOSX_DEPLOYMENT_TARGET = 10.14;
 				MTL_ENABLE_DEBUG_INFO = NO;
 				OTHER_LDFLAGS = (
 					"-lchaos_common",
@@ -8364,7 +8376,7 @@
 				);
 				INSTALL_PATH = "$(SRCROOT)/usr/local/lib";
 				LIBRARY_SEARCH_PATHS = "$(SRCROOT)/usr/local/lib";
-				MACOSX_DEPLOYMENT_TARGET = 10.10;
+				MACOSX_DEPLOYMENT_TARGET = 10.14;
 				MTL_ENABLE_DEBUG_INFO = YES;
 				OTHER_LDFLAGS = "-lchaos_common";
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -8410,7 +8422,7 @@
 				);
 				INSTALL_PATH = "$(SRCROOT)/usr/local/lib";
 				LIBRARY_SEARCH_PATHS = "$(SRCROOT)/usr/local/lib";
-				MACOSX_DEPLOYMENT_TARGET = 10.10;
+				MACOSX_DEPLOYMENT_TARGET = 10.14;
 				MTL_ENABLE_DEBUG_INFO = NO;
 				OTHER_LDFLAGS = "-lchaos_common";
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -8547,13 +8559,19 @@
 				CLANG_CXX_LIBRARY = "libc++";
 				COMPILER_INDEX_STORE_ENABLE = NO;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
+				GCC_OPTIMIZATION_LEVEL = 0;
 				GCC_PREPROCESSOR_DEFINITIONS = "CHAOS_PROMETHEUS=1";
 				HEADER_SEARCH_PATHS = (
 					.,
 					usr/local/include,
 				);
 				LIBRARY_SEARCH_PATHS = "$(SRCROOT)/usr/local/lib";
+				MACOSX_DEPLOYMENT_TARGET = 10.14;
 				ONLY_ACTIVE_ARCH = YES;
+				OTHER_CFLAGS = (
+					"-fno-stack-check",
+					"-fno-stack-protector",
+				);
 				OTHER_LDFLAGS = (
 					"-lboost_log_setup",
 					"-lboost_random",
@@ -8600,7 +8618,7 @@
 				);
 				INSTALL_PATH = "$(SRCROOT)/usr/local/lib";
 				LIBRARY_SEARCH_PATHS = "$(SRCROOT)/usr/local/lib";
-				MACOSX_DEPLOYMENT_TARGET = 10.10;
+				MACOSX_DEPLOYMENT_TARGET = 10.14;
 				ONLY_ACTIVE_ARCH = YES;
 				OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)";
 				OTHER_LDFLAGS = (
@@ -8642,7 +8660,7 @@
 				);
 				INSTALL_PATH = "$(SRCROOT)/usr/local/lib";
 				LIBRARY_SEARCH_PATHS = "$(SRCROOT)/usr/local/lib";
-				MACOSX_DEPLOYMENT_TARGET = 10.10;
+				MACOSX_DEPLOYMENT_TARGET = 10.14;
 				ONLY_ACTIVE_ARCH = YES;
 				OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)";
 				OTHER_LDFLAGS = (
@@ -8697,7 +8715,7 @@
 				);
 				INSTALL_PATH = "$(SRCROOT)/usr/local/lib";
 				LIBRARY_SEARCH_PATHS = "$(SRCROOT)/usr/local/lib";
-				MACOSX_DEPLOYMENT_TARGET = 10.10;
+				MACOSX_DEPLOYMENT_TARGET = 10.14;
 				MTL_ENABLE_DEBUG_INFO = YES;
 				OTHER_LDFLAGS = "-lchaos_common";
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -8758,7 +8776,7 @@
 				);
 				INSTALL_PATH = "$(SRCROOT)/usr/local/lib";
 				LIBRARY_SEARCH_PATHS = "$(SRCROOT)/usr/local/lib";
-				MACOSX_DEPLOYMENT_TARGET = 10.12;
+				MACOSX_DEPLOYMENT_TARGET = 10.14;
 				MTL_ENABLE_DEBUG_INFO = YES;
 				OTHER_LDFLAGS = "-lboost_system";
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -8800,7 +8818,7 @@
 				);
 				LD_RUNPATH_SEARCH_PATHS = "$(SRCROOT)/usr/local/lib";
 				LIBRARY_SEARCH_PATHS = "$(SRCROOT)/usr/local/lib";
-				MACOSX_DEPLOYMENT_TARGET = 10.10;
+				MACOSX_DEPLOYMENT_TARGET = 10.14;
 				ONLY_ACTIVE_ARCH = YES;
 				OTHER_LDFLAGS = (
 					"$(inherited)",
@@ -8864,7 +8882,7 @@
 					usr/local/include,
 				);
 				LIBRARY_SEARCH_PATHS = "$(SRCROOT)/usr/local/lib";
-				MACOSX_DEPLOYMENT_TARGET = 10.12;
+				MACOSX_DEPLOYMENT_TARGET = 10.14;
 				MTL_ENABLE_DEBUG_INFO = YES;
 				OTHER_LDFLAGS = (
 					"-lchaos_common",
@@ -8918,7 +8936,7 @@
 				);
 				LD_RUNPATH_SEARCH_PATHS = "$(SRCROOT)/usr/local/lib";
 				LIBRARY_SEARCH_PATHS = "$(SRCROOT)/usr/local/lib";
-				MACOSX_DEPLOYMENT_TARGET = 10.10;
+				MACOSX_DEPLOYMENT_TARGET = 10.14;
 				MTL_ENABLE_DEBUG_INFO = YES;
 				OTHER_LDFLAGS = (
 					"-lchaos_metadata_service_client",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c3cf53066c2fa806c6d90e251625f159546a50d7..e631a0776ee0b3860277f65edaba33af50b2f4fb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,5 +1,11 @@
 cmake_minimum_required(VERSION 2.8)
 MESSAGE("framework CMakeLists")
+
+# workaround for issues with MacOS 10.15 Catalina and stack_not_16_byte_aligned_error issues
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-stack-check -fno-stack-protector")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-stack-check -fno-stack-protector")
+
+
 IF(WIN32)
 add_definitions(-D_WIN32_WINNT=0x601)
 #include(config/CMakeChaosWin.txt)
@@ -175,7 +181,7 @@ IF (CHAOS_PROMETHEUS)
   ExternalProject_Add(
   prometheus
   GIT_REPOSITORY https://github.com/jupp0r/prometheus-cpp.git
-  GIT_TAG master
+  GIT_TAG v0.8.0
   PREFIX "${CMAKE_BINARY_DIR}/ext_dep/prometheus-prefix"
   SOURCE_DIR "${CMAKE_BINARY_DIR}/ext_dep/prometheus-src"
   BINARY_DIR "${CMAKE_BINARY_DIR}/ext_dep/prometheus-src"
@@ -213,7 +219,7 @@ if(NOT CHAOS_ONLY_DEPENDECY)
 
   MESG("Configure Chaos Micro Unit Toolkit")
   ADD_SUBDIRECTORY(chaos_micro_unit_toolkit)
-  
+
 endif()
 
 IF (CHAOS_AGENT AND NOT CHAOS_ONLY_DEPENDECY)
diff --git a/ChaosMetadataService/CMakeLists.txt b/ChaosMetadataService/CMakeLists.txt
index 48924eaae3963c79bf9b36d86d35eb0a2767b892..a4e881f711ec625a6f43a6f7642e9b4fdf93d409 100644
--- a/ChaosMetadataService/CMakeLists.txt
+++ b/ChaosMetadataService/CMakeLists.txt
@@ -1,5 +1,7 @@
 cmake_minimum_required(VERSION 2.8)
 project(ChaosMetadataService)
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-stack-check -fno-stack-protector")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-stack-check -fno-stack-protector")
 #add module path for permi to find lirary
 list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
 set(CMAKE_MACOSX_RPATH ON)
@@ -48,10 +50,11 @@ MESG("Install c mongodb driver")
 ExternalProject_Add(
  mongo-c-driver
  GIT_REPOSITORY https://github.com/mongodb/mongo-c-driver.git
- GIT_TAG 1.12.0
+ GIT_TAG 1.15.2
  PREFIX "${CMAKE_BINARY_DIR}/ext_dep/mongo-c-driver-prefix"
  SOURCE_DIR "${CMAKE_BINARY_DIR}/ext_dep/mongo-c-driver-src"
  BINARY_DIR "${CMAKE_BINARY_DIR}/ext_dep/mongo-c-driver-build"
+ BUILD_COMMAND make CFLAGS=${CMAKE_C_FLAGS} CXXFLAGS=${CMAKE_CXX_FLAGS}
  CMAKE_ARGS
   -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX} -DCMAKE_BUILD_TYPE=Release -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF -DENABLE_BSON=ONLY
  LOG_DOWNLOAD ON
@@ -63,10 +66,11 @@ ExternalProject_Add(
  mongo-cxx-driver
  DEPENDS mongo-c-driver
  GIT_REPOSITORY https://github.com/mongodb/mongo-cxx-driver
- GIT_TAG r3.3.0
+ GIT_TAG r3.3.1
  PREFIX "${CMAKE_BINARY_DIR}/ext_dep/mongo-cxx-driver-prefix"
  SOURCE_DIR "${CMAKE_BINARY_DIR}/ext_dep/mongo-cxx-driver-src"
  BINARY_DIR "${CMAKE_BINARY_DIR}/ext_dep/mongo-cxx-driver-build"
+ BUILD_COMMAND make CFLAGS=${CMAKE_C_FLAGS} CXXFLAGS=${CMAKE_CXX_FLAGS}
  CMAKE_ARGS
   -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX} -DCMAKE_BUILD_TYPE=Release
  LOG_DOWNLOAD ON
@@ -81,36 +85,36 @@ ExternalProject_Add(
  include_directories("${CMAKE_INSTALL_PREFIX}/include/libbson-1.0")
  include_directories("${CMAKE_INSTALL_PREFIX}/lib")
 
-MESG("Install libuv driver for cassandra dependecy")
-ExternalProject_Add(
- libuv-driver
- GIT_REPOSITORY https://github.com/libuv/libuv.git
- GIT_TAG v1.24.0
- PREFIX "${CMAKE_BINARY_DIR}/ext_dep/libuv-driver-prefix"
- SOURCE_DIR "${CMAKE_BINARY_DIR}/ext_dep/libuv-driver-src"
- BINARY_DIR "${CMAKE_BINARY_DIR}/ext_dep/libuv-driver-build"
- CMAKE_ARGS
-  -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX}
- LOG_DOWNLOAD ON
- LOG_CONFIGURE ON
- LOG_BUILD ON)
-
-MESG("Install Cassandra driver")
-ExternalProject_Add(
- cassandra-driver
- DEPENDS libuv-driver
- GIT_REPOSITORY https://github.com/datastax/cpp-driver.git
- GIT_TAG 2.10.0
- PREFIX "${CMAKE_BINARY_DIR}/ext_dep/cassandra-driver-prefix"
- SOURCE_DIR "${CMAKE_BINARY_DIR}/ext_dep/cassandra-driver-src"
- BINARY_DIR "${CMAKE_BINARY_DIR}/ext_dep/cassandra-driver-build"
- CMAKE_ARGS
-  -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX}
-  -DLIBUV_ROOT_DIR=${CMAKE_INSTALL_PREFIX}
-  -DCASS_USE_OPENSSL=OFF
- LOG_DOWNLOAD ON
- LOG_CONFIGURE ON
- LOG_BUILD ON)
+# MESG("Install libuv driver for cassandra dependecy")
+# ExternalProject_Add(
+#  libuv-driver
+#  GIT_REPOSITORY https://github.com/libuv/libuv.git
+#  GIT_TAG v1.24.0
+#  PREFIX "${CMAKE_BINARY_DIR}/ext_dep/libuv-driver-prefix"
+#  SOURCE_DIR "${CMAKE_BINARY_DIR}/ext_dep/libuv-driver-src"
+#  BINARY_DIR "${CMAKE_BINARY_DIR}/ext_dep/libuv-driver-build"
+#  CMAKE_ARGS
+#   -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX}
+#  LOG_DOWNLOAD ON
+#  LOG_CONFIGURE ON
+#  LOG_BUILD ON)
+
+# MESG("Install Cassandra driver")
+# ExternalProject_Add(
+#  cassandra-driver
+#  DEPENDS libuv-driver
+#  GIT_REPOSITORY https://github.com/datastax/cpp-driver.git
+#  GIT_TAG 2.10.0
+#  PREFIX "${CMAKE_BINARY_DIR}/ext_dep/cassandra-driver-prefix"
+#  SOURCE_DIR "${CMAKE_BINARY_DIR}/ext_dep/cassandra-driver-src"
+#  BINARY_DIR "${CMAKE_BINARY_DIR}/ext_dep/cassandra-driver-build"
+#  CMAKE_ARGS
+#   -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX}
+#   -DLIBUV_ROOT_DIR=${CMAKE_INSTALL_PREFIX}
+#   -DCASS_USE_OPENSSL=OFF
+#  LOG_DOWNLOAD ON
+#  LOG_CONFIGURE ON
+#  LOG_BUILD ON)
 
  include_directories(${LIBMONGOCXX_INCLUDE_DIR})
  include_directories(${LIBBSONCXX_INCLUDE_DIR})
@@ -307,8 +311,8 @@ SET(cnd_src  ${cnd_src} object_storage/hybdriver/ShardKeyManagement.cpp
                         object_storage/hybdriver/HybBaseDataAccess.cpp)
 
 #hybrid cassasndra storage driver
-SET(cnd_src  ${cnd_src} object_storage/hybdriver/cassandra/CassHybObjectStorageDriver.cpp
-                        object_storage/hybdriver/cassandra/CassHybDataAccess.cpp)
+# SET(cnd_src  ${cnd_src} object_storage/hybdriver/cassandra/CassHybObjectStorageDriver.cpp
+#                         object_storage/hybdriver/cassandra/CassHybDataAccess.cpp)
 
 SET(cnd_src  ${cnd_src}	batch/MDSBatchExecutor.cpp
                         batch/MDSBatchCommand.cpp)
@@ -345,7 +349,8 @@ ENDIF(CHAOS_PROMETHEUS)
 ADD_EXECUTABLE(${PROJECT_NAME} ${cnd_src})
 
 #add dependency
-add_dependencies(${PROJECT_NAME} mongo-cxx-driver cassandra-driver)
+add_dependencies(${PROJECT_NAME} mongo-cxx-driver)
+# add_dependencies(${PROJECT_NAME} cassandra-driver)
 
 FILE(GLOB files "../chaos_service_common/data/node/*.h")
 INSTALL(FILES ${files} DESTINATION include/chaos_service_common/data/node/)
@@ -367,10 +372,10 @@ SET(BUILD_LIBRARY ${BUILD_LIBRARY} mongocxx)
 SET(BUILD_LIBRARY ${BUILD_LIBRARY} bsoncxx)
 target_compile_definitions(${PROJECT_NAME} PRIVATE USE_MONGODB3_DRIVER=1)
 
-MESG("Enable link to cassandra and bsoncxx library")
-SET(BUILD_LIBRARY ${BUILD_LIBRARY} uv)
-SET(BUILD_LIBRARY ${BUILD_LIBRARY} cassandra)
-target_compile_definitions(${PROJECT_NAME} PRIVATE USE_CASSANDRA_DRIVER=1)
+# MESG("Enable link to cassandra and bsoncxx library")
+# SET(BUILD_LIBRARY ${BUILD_LIBRARY} uv)
+# SET(BUILD_LIBRARY ${BUILD_LIBRARY} cassandra)
+# target_compile_definitions(${PROJECT_NAME} PRIVATE USE_CASSANDRA_DRIVER=1)
 
 
 TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${BUILD_LIBRARY})
diff --git a/chaos/common/CMakeLists.txt b/chaos/common/CMakeLists.txt
index e92c50c66cbc15190d93f433bd9d5dcd12b69206..d005118926bbe51608e489c3dd558400dbcc50bd 100644
--- a/chaos/common/CMakeLists.txt
+++ b/chaos/common/CMakeLists.txt
@@ -3,6 +3,8 @@ project(chaos_common)
 #### required libraries
 MESSAGE(" CMAKELIST framework/chaos/common")
 MESSAGE ("CHAOS_TARGET:" ${CHAOS_TARGET})
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-stack-check")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-stack-check")
 if(WIN32)
 set(CMAKE_SUPPRESS_REGENERATION true)
 ELSE(WIN32)
diff --git a/chaos/cu_toolkit/CMakeLists.txt b/chaos/cu_toolkit/CMakeLists.txt
index e994de093dbfbd3c1905e82d53b0787203e7574b..cf548854485a2e9b9e3b448f30810cdf6140d461 100644
--- a/chaos/cu_toolkit/CMakeLists.txt
+++ b/chaos/cu_toolkit/CMakeLists.txt
@@ -1,6 +1,7 @@
 project(chaos_cutoolkit)
 if(WIN32)
-
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-stack-check")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-stack-check")
 set(CMAKE_SUPPRESS_REGENERATION true)
 INCLUDE_DIRECTORIES( ../../ ${ALL_WINDOWS_INCLUDE_DIR})
 INCLUDE_DIRECTORIES(${CMAKE_INSTALL_PREFIX}/boostinstall/include/boost-1_70)
diff --git a/chaos/cu_toolkit/control_manager/AbstractControlUnit.cpp b/chaos/cu_toolkit/control_manager/AbstractControlUnit.cpp
index b7aeb957ec501b08fe47898cd2580d201f507fb4..76ccdc0d1cc89e08b9d7e6088ad19aa84d0d73c8 100644
--- a/chaos/cu_toolkit/control_manager/AbstractControlUnit.cpp
+++ b/chaos/cu_toolkit/control_manager/AbstractControlUnit.cpp
@@ -64,59 +64,59 @@ using namespace chaos::cu::driver_manager::driver;
 #define S__LINE__ S_(__LINE__)
 
 #define CHEK_IF_NEED_TO_THROW(flag, code)                                                                                          \
-  try {                                                                                                                            \
-    code                                                                                                                           \
-  } catch (chaos::CException & ex) {                                                                                               \
-    ACULERR_ << "CHAOS Exception on " << DatasetDB::getDeviceID() << ":\n"                                                         \
-             << ex.what();                                                                                                         \
-    if (flag) throw chaos::common::exception::MetadataLoggingCException(getCUID(), ex.errorCode, ex.errorMessage, ex.errorDomain); \
-  } catch (...) {                                                                                                                  \
-    ACULERR_ << "Unknown exception on" << DatasetDB::getDeviceID();                                                                \
-    if (flag) throw chaos::common::exception::MetadataLoggingCException(getCUID(), -1000, S__LINE__, __PRETTY_FUNCTION__);         \
-  }
+try {                                                                                                                            \
+code                                                                                                                           \
+} catch (chaos::CException & ex) {                                                                                               \
+ACULERR_ << "CHAOS Exception on " << DatasetDB::getDeviceID() << ":\n"                                                         \
+<< ex.what();                                                                                                         \
+if (flag) throw chaos::common::exception::MetadataLoggingCException(getCUID(), ex.errorCode, ex.errorMessage, ex.errorDomain); \
+} catch (...) {                                                                                                                  \
+ACULERR_ << "Unknown exception on" << DatasetDB::getDeviceID();                                                                \
+if (flag) throw chaos::common::exception::MetadataLoggingCException(getCUID(), -1000, S__LINE__, __PRETTY_FUNCTION__);         \
+}
 
 #define GET_CAT_OR_EXIT(t, rv)              \
-  if (map_variable_catalog.count(t) == 0) { \
-    return rv;                              \
-  }                                         \
-  AlarmCatalog& catalog = map_variable_catalog[t];
+if (map_variable_catalog.count(t) == 0) { \
+return rv;                              \
+}                                         \
+AlarmCatalog& catalog = map_variable_catalog[t];
 
 #pragma mark StorageBurst
 StorageBurst::StorageBurst(DatasetBurstShrdPtr _dataset_burst)
-    : dataset_burst(_dataset_burst) {}
+: dataset_burst(_dataset_burst) {}
 
 StorageBurst::~StorageBurst() {}
 
 #pragma mark PushStorageBurst
 PushStorageBurst::PushStorageBurst(DatasetBurstShrdPtr _dataset_burst)
-    : StorageBurst(MOVE(_dataset_burst)), current_pushes(0) {}
+: StorageBurst(MOVE(_dataset_burst)), current_pushes(0) {}
 
 PushStorageBurst::~PushStorageBurst() {}
 #ifndef _WIN32
 bool PushStorageBurst::active(void* data __attribute__((unused))) {
 #else
-bool PushStorageBurst::active(void* data ) {
+    bool PushStorageBurst::active(void* data ) {
 #endif
-
-  return ++current_pushes < StorageBurst::dataset_burst->value.asUInt32();
-}
-
+        
+        return ++current_pushes < StorageBurst::dataset_burst->value.asUInt32();
+    }
+    
 #pragma mark MSecStorageBurst
-MSecStorageBurst::MSecStorageBurst(DatasetBurstShrdPtr _dataset_burst)
+    MSecStorageBurst::MSecStorageBurst(DatasetBurstShrdPtr _dataset_burst)
     : StorageBurst(MOVE(_dataset_burst)), timeout_msec(TimingUtil::getTimestampWithDelay(StorageBurst::dataset_burst->value.asInt32(), true)) {}
-
-MSecStorageBurst::~MSecStorageBurst() {}
-
-bool MSecStorageBurst::active(void* data) {
-  int64_t* now = static_cast<int64_t*>(data);
-  return timeout_msec > *now;
-}
-
+    
+    MSecStorageBurst::~MSecStorageBurst() {}
+    
+    bool MSecStorageBurst::active(void* data) {
+        int64_t* now = static_cast<int64_t*>(data);
+        return timeout_msec > *now;
+    }
+    
 #pragma mark AbstractControlUnit
-//! Contructor with type and id
-AbstractControlUnit::AbstractControlUnit(const std::string& _control_unit_type,
-                                         const std::string& _control_unit_id,
-                                         const std::string& _control_unit_param)
+    //! Contructor with type and id
+    AbstractControlUnit::AbstractControlUnit(const std::string& _control_unit_type,
+                                             const std::string& _control_unit_id,
+                                             const std::string& _control_unit_param)
     : DatasetDB(GlobalConfiguration::getInstance()->getOption<bool>(CU_OPT_IN_MEMORY_DATABASE)), control_key("none"),
 #ifdef CONTROL_UNIT_INSTANCE_RANDOM
     control_unit_instance(UUIDUtil::generateUUIDLite())
@@ -141,18 +141,18 @@ AbstractControlUnit::AbstractControlUnit(const std::string& _control_unit_type,
     , timestamp_hw_acq_cached_value()
     , thread_schedule_daly_cached_value()
     , key_data_storage() {
-  _initPropertyGroup();
-  //!try to decode parameter string has json document
-  is_control_unit_json_param = json_reader.parse(control_unit_param, json_parameter_document);
-  //initialize check list
-  _initChecklist();
-}
-
-//! Contructor with driver
-AbstractControlUnit::AbstractControlUnit(const std::string&           _control_unit_type,
-                                         const std::string&           _control_unit_id,
-                                         const std::string&           _control_unit_param,
-                                         const ControlUnitDriverList& _control_unit_drivers)
+        _initPropertyGroup();
+        //!try to decode parameter string has json document
+        is_control_unit_json_param = json_reader.parse(control_unit_param, json_parameter_document);
+        //initialize check list
+        _initChecklist();
+    }
+    
+    //! Contructor with driver
+    AbstractControlUnit::AbstractControlUnit(const std::string&           _control_unit_type,
+                                             const std::string&           _control_unit_id,
+                                             const std::string&           _control_unit_param,
+                                             const ControlUnitDriverList& _control_unit_drivers)
     : DatasetDB(GlobalConfiguration::getInstance()->getOption<bool>(CU_OPT_IN_MEMORY_DATABASE)), control_key("none"),
 #ifdef CONTROL_UNIT_INSTANCE_RANDOM
     control_unit_instance(UUIDUtil::generateUUIDLite())
@@ -176,2147 +176,2201 @@ AbstractControlUnit::AbstractControlUnit(const std::string&           _control_u
     , timestamp_hw_acq_cached_value()
     , thread_schedule_daly_cached_value()
     , key_data_storage() {
-  _initPropertyGroup();
-  //!try to decode parameter string has json document
-  is_control_unit_json_param = json_reader.parse(control_unit_param, json_parameter_document);
-  //copy array
-  for (int idx = 0; idx < _control_unit_drivers.size(); idx++) {
-    control_unit_drivers.push_back(_control_unit_drivers[idx]);
-  }
-
-  //initialize check list
-  _initChecklist();
-}
-
-void AbstractControlUnit::_initDrivers() {
-  ACULAPP_ << "Initializating Driver Accessors";
-  //at this point and before the unit implementation init i need to get
-  //the infromation about the needed drivers
-  std::vector<DrvRequestInfo> unit_needed_drivers;
-
-  //got the needded driver definition
-  unitDefineDriver(unit_needed_drivers);
-
-  accessor_instances.clear();
-  for (int idx = 0;
-       idx != unit_needed_drivers.size();
-       idx++) {
-    driver_manager::driver::DriverAccessor* accessor_instance = driver_manager::DriverManager::getInstance()->getNewAccessorForDriverInstance(unit_needed_drivers[idx]);
-    accessor_instances.push_back(accessor_instance);
-  }
-}
-
-void AbstractControlUnit::_initChecklist() {
-  //init checklists
-  check_list_sub_service.addCheckList("_init");
-  check_list_sub_service.getSharedCheckList("_init")->addElement(INIT_RPC_PHASE_CALL_INIT_STATE);
-  check_list_sub_service.getSharedCheckList("_init")->addElement(INIT_RPC_PHASE_INIT_SHARED_CACHE);
-  check_list_sub_service.getSharedCheckList("_init")->addElement(INIT_RPC_PHASE_COMPLETE_OUTPUT_ATTRIBUTE);
-  check_list_sub_service.getSharedCheckList("_init")->addElement(INIT_RPC_PHASE_COMPLETE_INPUT_ATTRIBUTE);
-  check_list_sub_service.getSharedCheckList("_init")->addElement(INIT_RPC_PHASE_INIT_SYSTEM_CACHE);
-  check_list_sub_service.getSharedCheckList("_init")->addElement(INIT_RPC_PHASE_CALL_UNIT_DEFINE_ATTRIBUTE);
-  check_list_sub_service.getSharedCheckList("_init")->addElement(INIT_RPC_PHASE_CREATE_FAST_ACCESS_CASCHE_VECTOR);
-  check_list_sub_service.getSharedCheckList("_init")->addElement(INIT_RPC_PHASE_CALL_UNIT_INIT);
-  check_list_sub_service.getSharedCheckList("_init")->addElement(INIT_RPC_PHASE_UPDATE_CONFIGURATION);
-  check_list_sub_service.getSharedCheckList("_init")->addElement(INIT_RPC_PHASE_PUSH_DATASET);
-
-  check_list_sub_service.addCheckList("init");
-  check_list_sub_service.getSharedCheckList("init")->addElement(INIT_SM_PHASE_INIT_DB);
-  check_list_sub_service.getSharedCheckList("init")->addElement(INIT_SM_PHASE_CREATE_DATA_STORAGE);
-
-  check_list_sub_service.addCheckList("_start");
-  check_list_sub_service.getSharedCheckList("_start")->addElement(START_RPC_PHASE_UNIT);
-  check_list_sub_service.getSharedCheckList("_start")->addElement(START_RPC_PHASE_IMPLEMENTATION);
-
-  check_list_sub_service.addCheckList("start");
-  check_list_sub_service.getSharedCheckList("start")->addElement(START_SM_PHASE_STAT_TIMER);
-}
-
-void AbstractControlUnit::_initPropertyGroup() {
-  PropertyGroup& pg_abstract_cu = addGroup(chaos::ControlUnitPropertyKey::P_GROUP_NAME);
-  pg_abstract_cu.addProperty(ControlUnitDatapackSystemKey::BYPASS_STATE, "Put control unit in bypass state", DataType::TYPE_BOOLEAN, 0, CDataVariant((bool)false));
-  pg_abstract_cu.addProperty(DataServiceNodeDefinitionKey::DS_STORAGE_TYPE, "Set the control unit storage type", DataType::TYPE_INT32, 0, CDataVariant((int32_t)0));
-  pg_abstract_cu.addProperty(DataServiceNodeDefinitionKey::DS_STORAGE_LIVE_TIME, "Set the control unit storage type", DataType::TYPE_INT64, 0, CDataVariant((int64_t)0));
-  pg_abstract_cu.addProperty(DataServiceNodeDefinitionKey::DS_STORAGE_HISTORY_TIME, "Set the control unit storage type", DataType::TYPE_INT64, 0, CDataVariant((int64_t)0));
-  //    CDWUniquePtr burst_type_desc(new CDataWrapper());
-  //    burst_type_desc->addInt32Value(DataServiceNodeDefinitionKey::DS_HISTORY_BURST_TYPE, DataServiceNodeDefinitionType::DSStorageBurstTypeUndefined);
-  //    pg_abstract_cu.addProperty(DataServiceNodeDefinitionKey::DS_HISTORY_BURST, "Specify if the restore operation need to be done as real operation or not", DataType::TYPE_CLUSTER,0, CDataVariant(burst_type_desc.release()));
-
-  pg_abstract_cu.addProperty(ControlUnitDatapackSystemKey::THREAD_SCHEDULE_DELAY, "Set the control unit step repeat time in microseconds", DataType::TYPE_INT64, 0, CDataVariant((int64_t)1000000));  //set to one seconds
-  pg_abstract_cu.addProperty(ControlUnitPropertyKey::INIT_RESTORE_OPTION, "Specify the restore type operatio to do durint initialization phase", DataType::TYPE_INT32, 0, CDataVariant((int32_t)0));
-  pg_abstract_cu.addProperty(ControlUnitPropertyKey::INIT_RESTORE_APPLY, "Specify if the restore operation need to be done as real operation or not", DataType::TYPE_BOOLEAN, 0, CDataVariant((bool)false));
-
-  PropertyCollector::setPropertyValueChangeFunction(ChaosBind(&AbstractControlUnit::propertyChangeHandler, this, ChaosBindPlaceholder(_1), ChaosBindPlaceholder(_2), ChaosBindPlaceholder(_3)));
-  PropertyCollector::setPropertyValueUpdatedFunction(ChaosBind(&AbstractControlUnit::propertyUpdatedHandler, this, ChaosBindPlaceholder(_1), ChaosBindPlaceholder(_2), ChaosBindPlaceholder(_3), ChaosBindPlaceholder(_4)));
-}
-
-/*!
- Destructor a new CU with an identifier
- */
-AbstractControlUnit::~AbstractControlUnit() {
-  //clear the accessor of the driver
-  for (int idx = 0;
-       idx != accessor_instances.size();
-       idx++) {
-    driver_manager::DriverManager::getInstance()->releaseAccessor(accessor_instances[idx]);
-  }
-  //clear the vector
-  accessor_instances.clear();
-}
-
-/*
- return the CU name
- */
-const std::string& AbstractControlUnit::getCUInstance() {
-  return control_unit_instance;
-};
-
-const std::string& AbstractControlUnit::getCUID() {
-  return control_unit_id;
-}
-
-const std::string& AbstractControlUnit::getCUParam() {
-  return control_unit_param;
-}
-
-const bool AbstractControlUnit::isCUParamInJson() {
-  return is_control_unit_json_param;
-}
-
-const Json::Value& AbstractControlUnit::getCUParamJsonRootElement() {
-  return json_parameter_document;
-}
-
-const std::string& AbstractControlUnit::getCUType() {
-  return control_unit_type;
-}
-
-/*
- fill the CDataWrapper with AbstractCU system configuration, this method
- is called after getStartConfiguration directly by sandbox. in this method
- are defined the action for the input element of the dataset
- */
-void AbstractControlUnit::_defineActionAndDataset(CDataWrapper& setup_configuration) {
-  vector<std::string> tempStringVector;
-
-  if (control_unit_id.size()) {
-    setDeviceID(control_unit_id);
-  }
-
-  //add the CU isntance, this can be redefinide by user in the unitDefineActionAndDataset method
-  //for let the CU have the same instance at every run
-  setup_configuration.addStringValue(NodeDefinitionKey::NODE_RPC_DOMAIN, control_unit_instance);
-
-  //if we have a control key we attach it
-  setup_configuration.addStringValue("mds_control_key", control_key);
-
-  //add the control unit type with semantonc type::subtype
-  setup_configuration.addStringValue(NodeDefinitionKey::NODE_TYPE, NodeType::NODE_TYPE_CONTROL_UNIT);
-  setup_configuration.addStringValue(NodeDefinitionKey::NODE_SUB_TYPE, control_unit_type);
-  //check if as been setuped a file for configuration
-  //LCU_ << "Check if as been setup a json file path to configura CU:" << CU_IDENTIFIER_C_STREAM;
-  //loadCDataWrapperForJsonFile(setup_configuration);
-
-  //first call the setup abstract method used by the implementing CU to define action, dataset and other
-  //usefull value
-  unitDefineActionAndDataset();
-
-  //call method to dinamically add other things to the dataset
-  _completeDatasetAttribute();
-
-  //for now we need only to add custom action for expose to rpc
-  //input element of the dataset
-  AbstActionDescShrPtr
-      action_description = addActionDescritionInstance<AbstractControlUnit>(this,
-                                                                            &AbstractControlUnit::_setDatasetAttribute,
-                                                                            ControlUnitNodeDomainAndActionRPC::CONTROL_UNIT_APPLY_INPUT_DATASET_ATTRIBUTE_CHANGE_SET,
-                                                                            "method for set the input element for the dataset");
-
-  //expose updateConfiguration Methdo to rpc
-  action_description = addActionDescritionInstance<AbstractControlUnit>(this,
-                                                                        &AbstractControlUnit::updateConfiguration,
-                                                                        NodeDomainAndActionRPC::ACTION_UPDATE_PROPERTY,
-                                                                        "Update control unit property");
-
-  action_description = addActionDescritionInstance<AbstractControlUnit>(this,
-                                                                        &AbstractControlUnit::_init,
-                                                                        NodeDomainAndActionRPC::ACTION_NODE_INIT,
-                                                                        "Perform the control unit initialization");
-
-  action_description = addActionDescritionInstance<AbstractControlUnit>(this,
-                                                                        &AbstractControlUnit::_deinit,
-                                                                        NodeDomainAndActionRPC::ACTION_NODE_DEINIT,
-                                                                        "Perform the control unit deinitialization");
-  action_description = addActionDescritionInstance<AbstractControlUnit>(this,
-                                                                        &AbstractControlUnit::_start,
-                                                                        NodeDomainAndActionRPC::ACTION_NODE_START,
-                                                                        "Start the control unit scheduling");
-
-  action_description = addActionDescritionInstance<AbstractControlUnit>(this,
-                                                                        &AbstractControlUnit::_stop,
-                                                                        NodeDomainAndActionRPC::ACTION_NODE_STOP,
-                                                                        "Stop the control unit scheduling");
-
-  action_description = addActionDescritionInstance<AbstractControlUnit>(this,
-                                                                        &AbstractControlUnit::_recover,
-                                                                        NodeDomainAndActionRPC::ACTION_NODE_RECOVER,
-                                                                        "Recovery a recoverable state, going to the last state");
-
-  action_description = addActionDescritionInstance<AbstractControlUnit>(this,
-                                                                        &AbstractControlUnit::_unitRestoreToSnapshot,
-                                                                        NodeDomainAndActionRPC::ACTION_NODE_RESTORE,
-                                                                        "Restore contorl unit to a snapshot tag");
-
-  action_description = addActionDescritionInstance<AbstractControlUnit>(this,
-                                                                        &AbstractControlUnit::_getState,
-                                                                        NodeDomainAndActionRPC::ACTION_NODE_GET_STATE,
-                                                                        "Get the state of the running control unit");
-
-  action_description = addActionDescritionInstance<AbstractControlUnit>(this,
-                                                                        &AbstractControlUnit::_getInfo,
-                                                                        NodeDomainAndActionRPC::ACTION_CU_GET_INFO,
-                                                                        "Get the information about running control unit");
-  action_description = addActionDescritionInstance<AbstractControlUnit>(this,
-                                                                        &AbstractControlUnit::_submitStorageBurst,
-                                                                        ControlUnitNodeDomainAndActionRPC::ACTION_STORAGE_BURST,
-                                                                        "Execute a storage burst on control unit");
-  action_description->addParam(ControlUnitNodeDefinitionKey::CONTROL_UNIT_DATASET_HISTORY_BURST_TAG, DataType::TYPE_STRING, "Tag associated to the stored data during burst");
-  action_description->addParam(ControlUnitNodeDefinitionKey::CONTROL_UNIT_DATASET_HISTORY_BURST_TYPE, DataType::TYPE_INT32, "The type of burst");
-  action_description->addParam(ControlUnitNodeDefinitionKey::CONTROL_UNIT_DATASET_HISTORY_BURST_VALUE, DataType::TYPE_UNDEFINED, "The value of the burst is defined by the type");
-
-  action_description = addActionDescritionInstance<AbstractControlUnit>(this,
-                                                                        &AbstractControlUnit::_datasetTagManagement,
-                                                                        ControlUnitNodeDomainAndActionRPC::ACTION_DATASET_TAG_MANAGEMENT,
-                                                                        "Execute a storage burst on control unit");
-  action_description->addParam(ControlUnitNodeDomainAndActionRPC::ACTION_DATASET_TAG_MANAGEMENT_ADD_LIST, DataType::TYPE_ACCESS_ARRAY, "List of tag to be added to the control unit dataset");
-  action_description->addParam(ControlUnitNodeDomainAndActionRPC::ACTION_DATASET_TAG_MANAGEMENT_REMOVE_LIST, DataType::TYPE_ACCESS_ARRAY, "List of tag to be removed to the control unit dataset");
-  //grab dataset description
-  DatasetDB::fillDataWrapperWithDataSetDescription(setup_configuration);
-
-  //    //get action description
-  //    getActionDescrionsInDataWrapper(setup_configuration);
-
-  //add property description
-  PropertyCollector::fillDescription("property", setup_configuration);
-}
-
-void AbstractControlUnit::unitDefineDriver(std::vector<DrvRequestInfo>& neededDriver) {
-  for (ControlUnitDriverListIterator iter = control_unit_drivers.begin();
-       iter != control_unit_drivers.end();
-       iter++) {
-    //copy driver info to the system array reference
-    neededDriver.push_back(*iter);
-  }
-}
-
-void AbstractControlUnit::unitDefineCustomAttribute() {
-}
-
-void AbstractControlUnit::_undefineActionAndDataset() {
-  ACULDBG_ << "Remove Action Description";
-  unitUndefineActionAndDataset();
-}
-
-void AbstractControlUnit::unitUndefineActionAndDataset() {
-}
-
-//! Get all managem declare action instance
-void AbstractControlUnit::_getDeclareActionInstance(std::vector<const chaos::DeclareAction*>& declareActionInstance) {
-  declareActionInstance.push_back(this);
-}
-
-//----------------------------------------- checklist method ------------------------------------------------
-#pragma mark checklist method
-void         AbstractControlUnit::doInitRpCheckList() {
-  std::vector<std::string> attribute_names;
-  //rpc initialize service
-  CHAOS_CHECK_LIST_START_SCAN_TO_DO(check_list_sub_service, "_init") {
-    CHAOS_CHECK_LIST_DONE(check_list_sub_service, "_init", INIT_RPC_PHASE_CALL_INIT_STATE) {
-      //call init sequence
-      init(NULL);
-      break;
-    }
-    CHAOS_CHECK_LIST_DONE(check_list_sub_service, "_init", INIT_RPC_PHASE_INIT_SHARED_CACHE) {
-      ACULAPP_ << "Allocate the user cache wrapper for:" + DatasetDB::getDeviceID();
-      attribute_shared_cache_wrapper = new AttributeSharedCacheWrapper(attribute_value_shared_cache);
-
-      ACULAPP_ << "Populating shared attribute cache for input attribute";
-      DatasetDB::getDatasetAttributesName(DataType::Input, attribute_names);
-      DatasetDB::getDatasetAttributesName(DataType::Bidirectional, attribute_names);
-      initAttributeOnSharedAttributeCache(DOMAIN_INPUT, attribute_names);
-
-      ACULAPP_ << "Populating shared attribute cache for output attribute";
-      attribute_names.clear();
-      DatasetDB::getDatasetAttributesName(DataType::Output, attribute_names);
-      DatasetDB::getDatasetAttributesName(DataType::Bidirectional, attribute_names);
-      initAttributeOnSharedAttributeCache(DOMAIN_OUTPUT, attribute_names);
-      break;
+        _initPropertyGroup();
+        //!try to decode parameter string has json document
+        is_control_unit_json_param = json_reader.parse(control_unit_param, json_parameter_document);
+        //copy array
+        for (int idx = 0; idx < _control_unit_drivers.size(); idx++) {
+            control_unit_drivers.push_back(_control_unit_drivers[idx]);
+        }
+        
+        //initialize check list
+        _initChecklist();
     }
-
-    CHAOS_CHECK_LIST_DONE(check_list_sub_service, "_init", INIT_RPC_PHASE_COMPLETE_OUTPUT_ATTRIBUTE) {
-      ACULAPP_ << "Complete shared attribute cache for output attribute";
-      completeOutputAttribute();
-      break;
+    
+    void AbstractControlUnit::_initDrivers() {
+        ACULAPP_ << "Initializating Driver Accessors";
+        //at this point and before the unit implementation init i need to get
+        //the infromation about the needed drivers
+        std::vector<DrvRequestInfo> unit_needed_drivers;
+        
+        //got the needded driver definition
+        unitDefineDriver(unit_needed_drivers);
+        
+        accessor_instances.clear();
+        for (int idx = 0;
+             idx != unit_needed_drivers.size();
+             idx++) {
+            driver_manager::driver::DriverAccessor* accessor_instance = driver_manager::DriverManager::getInstance()->getNewAccessorForDriverInstance(unit_needed_drivers[idx]);
+            accessor_instances.push_back(accessor_instance);
+        }
     }
-    CHAOS_CHECK_LIST_DONE(check_list_sub_service, "_init", INIT_RPC_PHASE_COMPLETE_INPUT_ATTRIBUTE) {
-      ACULAPP_ << "Complete shared attribute cache for input attribute";
-      completeInputAttribute();
-      break;
+    
+    void AbstractControlUnit::_initChecklist() {
+        //init checklists
+        check_list_sub_service.addCheckList("_init");
+        check_list_sub_service.getSharedCheckList("_init")->addElement(INIT_RPC_PHASE_CALL_INIT_STATE);
+        check_list_sub_service.getSharedCheckList("_init")->addElement(INIT_RPC_PHASE_INIT_SHARED_CACHE);
+        check_list_sub_service.getSharedCheckList("_init")->addElement(INIT_RPC_PHASE_COMPLETE_OUTPUT_ATTRIBUTE);
+        check_list_sub_service.getSharedCheckList("_init")->addElement(INIT_RPC_PHASE_COMPLETE_INPUT_ATTRIBUTE);
+        check_list_sub_service.getSharedCheckList("_init")->addElement(INIT_RPC_PHASE_INIT_SYSTEM_CACHE);
+        check_list_sub_service.getSharedCheckList("_init")->addElement(INIT_RPC_PHASE_CALL_UNIT_DEFINE_ATTRIBUTE);
+        check_list_sub_service.getSharedCheckList("_init")->addElement(INIT_RPC_PHASE_CREATE_FAST_ACCESS_CASCHE_VECTOR);
+        check_list_sub_service.getSharedCheckList("_init")->addElement(INIT_RPC_PHASE_CALL_UNIT_INIT);
+        check_list_sub_service.getSharedCheckList("_init")->addElement(INIT_RPC_PHASE_UPDATE_CONFIGURATION);
+        check_list_sub_service.getSharedCheckList("_init")->addElement(INIT_RPC_PHASE_PUSH_DATASET);
+        
+        check_list_sub_service.addCheckList("init");
+        check_list_sub_service.getSharedCheckList("init")->addElement(INIT_SM_PHASE_INIT_DB);
+        check_list_sub_service.getSharedCheckList("init")->addElement(INIT_SM_PHASE_CREATE_DATA_STORAGE);
+        
+        check_list_sub_service.addCheckList("_start");
+        check_list_sub_service.getSharedCheckList("_start")->addElement(START_RPC_PHASE_UNIT);
+        check_list_sub_service.getSharedCheckList("_start")->addElement(START_RPC_PHASE_IMPLEMENTATION);
+        
+        check_list_sub_service.addCheckList("start");
+        check_list_sub_service.getSharedCheckList("start")->addElement(START_SM_PHASE_STAT_TIMER);
     }
-
-    CHAOS_CHECK_LIST_DONE(check_list_sub_service, "_init", INIT_RPC_PHASE_INIT_SYSTEM_CACHE) {
-      ACULAPP_ << "Populating shared attribute cache for system attribute";
-      initSystemAttributeOnSharedAttributeCache();
-      break;
+    
+    void AbstractControlUnit::_initPropertyGroup() {
+        PropertyGroup& pg_abstract_cu = addGroup(chaos::ControlUnitPropertyKey::P_GROUP_NAME);
+        pg_abstract_cu.addProperty(ControlUnitDatapackSystemKey::BYPASS_STATE, "Put control unit in bypass state", DataType::TYPE_BOOLEAN, 0, CDataVariant((bool)false));
+        pg_abstract_cu.addProperty(DataServiceNodeDefinitionKey::DS_STORAGE_TYPE, "Set the control unit storage type", DataType::TYPE_INT32, 0, CDataVariant((int32_t)0));
+        pg_abstract_cu.addProperty(DataServiceNodeDefinitionKey::DS_STORAGE_LIVE_TIME, "Set the control unit storage type", DataType::TYPE_INT64, 0, CDataVariant((int64_t)0));
+        pg_abstract_cu.addProperty(DataServiceNodeDefinitionKey::DS_STORAGE_HISTORY_TIME, "Set the control unit storage type", DataType::TYPE_INT64, 0, CDataVariant((int64_t)0));
+        //    CDWUniquePtr burst_type_desc(new CDataWrapper());
+        //    burst_type_desc->addInt32Value(DataServiceNodeDefinitionKey::DS_HISTORY_BURST_TYPE, DataServiceNodeDefinitionType::DSStorageBurstTypeUndefined);
+        //    pg_abstract_cu.addProperty(DataServiceNodeDefinitionKey::DS_HISTORY_BURST, "Specify if the restore operation need to be done as real operation or not", DataType::TYPE_CLUSTER,0, CDataVariant(burst_type_desc.release()));
+        
+        pg_abstract_cu.addProperty(ControlUnitDatapackSystemKey::THREAD_SCHEDULE_DELAY, "Set the control unit step repeat time in microseconds", DataType::TYPE_INT64, 0, CDataVariant((int64_t)1000000));  //set to one seconds
+        pg_abstract_cu.addProperty(ControlUnitPropertyKey::INIT_RESTORE_OPTION, "Specify the restore type operatio to do durint initialization phase", DataType::TYPE_INT32, 0, CDataVariant((int32_t)0));
+        pg_abstract_cu.addProperty(ControlUnitPropertyKey::INIT_RESTORE_APPLY, "Specify if the restore operation need to be done as real operation or not", DataType::TYPE_BOOLEAN, 0, CDataVariant((bool)false));
+        
+        PropertyCollector::setPropertyValueChangeFunction(ChaosBind(&AbstractControlUnit::propertyChangeHandler, this, ChaosBindPlaceholder(_1), ChaosBindPlaceholder(_2), ChaosBindPlaceholder(_3)));
+        PropertyCollector::setPropertyValueUpdatedFunction(ChaosBind(&AbstractControlUnit::propertyUpdatedHandler, this, ChaosBindPlaceholder(_1), ChaosBindPlaceholder(_2), ChaosBindPlaceholder(_3), ChaosBindPlaceholder(_4)));
     }
-    CHAOS_CHECK_LIST_DONE(check_list_sub_service, "_init", INIT_RPC_PHASE_CALL_UNIT_DEFINE_ATTRIBUTE) {
-      std::string cu_load_param=getCUParam();
-
-      if(isCUParamInJson()){
-        getAttributeCache()->addCustomAttribute(chaos::ControlUnitNodeDefinitionKey::CONTROL_UNIT_LOAD_PARAM, cu_load_param.size(),
-                                          chaos::DataType::TYPE_CLUSTER);
-      } else {
-        getAttributeCache()->addCustomAttribute(chaos::ControlUnitNodeDefinitionKey::CONTROL_UNIT_LOAD_PARAM, cu_load_param.size(),
-                                          chaos::DataType::TYPE_STRING);
-      }
-      getAttributeCache()->setCustomAttributeValue(chaos::ControlUnitNodeDefinitionKey::CONTROL_UNIT_LOAD_PARAM, (void *)cu_load_param.c_str(),
-                                               cu_load_param.size());
-      
-      //define the implementations custom variable
-      unitDefineCustomAttribute();
-      break;
-    }
-    CHAOS_CHECK_LIST_DONE(check_list_sub_service, "_init", INIT_RPC_PHASE_CREATE_FAST_ACCESS_CASCHE_VECTOR) {
-      //create fast vector access for cached value
-      fillCachedValueVector(attribute_value_shared_cache->getSharedDomain(DOMAIN_OUTPUT),
-                            cache_output_attribute_vector);
-
-      fillCachedValueVector(attribute_value_shared_cache->getSharedDomain(DOMAIN_INPUT),
-                            cache_input_attribute_vector);
-
-      fillCachedValueVector(attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM),
-                            cache_system_attribute_vector);
-
-      fillCachedValueVector(attribute_value_shared_cache->getSharedDomain(DOMAIN_CUSTOM),
-                            cache_custom_attribute_vector);
-      break;
-    }
-    CHAOS_CHECK_LIST_DONE(check_list_sub_service, "_init", INIT_RPC_PHASE_CALL_UNIT_INIT) {
-      //initialize implementations
-      unitInit();
-      break;
-    }
-    CHAOS_CHECK_LIST_DONE(check_list_sub_service, "_init", INIT_RPC_PHASE_UPDATE_CONFIGURATION) {
-      //call update param function
-      updateConfiguration(MOVE(init_configuration->clone()));
-
-      //check if we need to do a restore on first start
-      PropertyGroupShrdPtr cug = PropertyCollector::getGroup(chaos::ControlUnitPropertyKey::P_GROUP_NAME);
-      if (cug.get()) {
-        if (cug->hasProperty(chaos::ControlUnitPropertyKey::INIT_RESTORE_APPLY) &&
-            cug->getProperty(chaos::ControlUnitPropertyKey::INIT_RESTORE_APPLY).getPropertyValue().isValid() &&
-            cug->getProperty(chaos::ControlUnitPropertyKey::INIT_RESTORE_APPLY).getPropertyValue().asBool()) {
-          //we need to add to stsart phase the restore one
-          check_list_sub_service.getSharedCheckList("_start")->addElement(START_RPC_PHASE_RESTORE_ON_FIRST_START);
-        }
-      }
-      break;
-    }
-    CHAOS_CHECK_LIST_DONE(check_list_sub_service, "_init", INIT_RPC_PHASE_PUSH_DATASET) {
-      //init on shared cache the all the dataaset with the default value
-      //set first timestamp for simulate the run step
-      int err;
-      *timestamp_acq_cached_value->getValuePtr<uint64_t>() = TimingUtil::getTimeStamp();
-      attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM).markAllAsChanged();
-      /*
-      *if ((err = pushSystemDataset()) != 0) {
-        ACULWRN_ << "cannot initialize system dataset, retrying";
-        sleep(1);
-        if ((err = pushSystemDataset()) != 0) {
-          throw CException(err, "cannot initialize system dataset", __PRETTY_FUNCTION__);
-        }
-      }
-      */
-      if ((err = pushSystemDataset()) != 0) {
-          throw CException(err, "cannot initialize system dataset (check live services)", __PRETTY_FUNCTION__);
-      }
-      /*if ((err = pushCUAlarmDataset()) != 0) {
-        ACULWRN_ << "cannot initialize CUAlarm dataset, retrying";
-        sleep(1);
-        if ((err = pushCUAlarmDataset()) != 0) {
-          throw CException(err, "cannot initialize CU alarm dataset", __PRETTY_FUNCTION__);
-        }
-      }*/
-      if ((err = pushCUAlarmDataset()) != 0) {
-          throw CException(err, "cannot initialize CU alarm dataset (check live services)", __PRETTY_FUNCTION__);
-      }
-      /*if ((err = pushDevAlarmDataset()) != 0) {
-        ACULWRN_ << "cannot initialize DEVAlarm dataset, retrying";
-        if ((err = pushDevAlarmDataset()) != 0) {
-          throw CException(err, "cannot initialize DEV alarm dataset", __PRETTY_FUNCTION__);
-        }
-      }*/
-      if ((err = pushDevAlarmDataset()) != 0) {
-          throw CException(err, "cannot initialize DEV alarm dataset (check live services)", __PRETTY_FUNCTION__);
-      }
-      attribute_value_shared_cache->getSharedDomain(DOMAIN_OUTPUT).markAllAsChanged();
-      // if the CU can't push initial dataset is a real problem, we must detect immediately
-     /* if ((err = pushOutputDataset()) != 0) {
-        ACULWRN_ << "cannot initialize output dataset, err:"<<err<<" retrying..";
-        sleep(1);
-        if ((err = pushOutputDataset()) != 0) {
-          throw CException(err, "cannot initialize output dataset", __PRETTY_FUNCTION__);
-        }
-      }*/
-        if ((err = pushOutputDataset()) != 0) {
-          throw CException(err, "cannot initialize output dataset (check live services)", __PRETTY_FUNCTION__);
-        }
-      attribute_value_shared_cache->getSharedDomain(DOMAIN_INPUT).markAllAsChanged();
-
-      /*
-      if ((err = pushInputDataset()) != 0) {
-        ACULWRN_ << "cannot initialize input dataset, retrying";
-        sleep(1);
-        if ((err = pushInputDataset()) != 0) {
-          throw CException(err, "cannot initialize input dataset", __PRETTY_FUNCTION__);
-        }
-      }*/
-      if ((err = pushInputDataset()) != 0) {
-          throw CException(err, "cannot initialize input dataset (check live services)", __PRETTY_FUNCTION__);
-        }
-      
-      attribute_value_shared_cache->getSharedDomain(DOMAIN_CUSTOM).markAllAsChanged();
-
-      if ((err = pushCustomDataset()) != 0) {
-        throw CException(err, "cannot initialize custom dataset (check live services)", __PRETTY_FUNCTION__);
-      }
-      break;
+    
+    /*!
+     Destructor a new CU with an identifier
+     */
+    AbstractControlUnit::~AbstractControlUnit() {
+        //clear the accessor of the driver
+        for (int idx = 0;
+             idx != accessor_instances.size();
+             idx++) {
+            driver_manager::DriverManager::getInstance()->releaseAccessor(accessor_instances[idx]);
+        }
+        //clear the vector
+        accessor_instances.clear();
     }
-  }
-  CHAOS_CHECK_LIST_END_SCAN_TO_DO(check_list_sub_service, "_init")
-}
-void AbstractControlUnit::doInitSMCheckList() {
-  //rpc initialize service
-  CHAOS_CHECK_LIST_START_SCAN_TO_DO(check_list_sub_service, "init") {
-    CHAOS_CHECK_LIST_DONE(check_list_sub_service, "init", INIT_SM_PHASE_INIT_DB) {
-      //cast to the CDatawrapper instance
-      ACULAPP_ << "Initialize CU Database for device:" << DatasetDB::getDeviceID();
-      run_id = CDW_GET_INT64_WITH_DEFAULT(init_configuration, ControlUnitNodeDefinitionKey::CONTROL_UNIT_RUN_ID, 0);
-      DatasetDB::addAttributeToDataSetFromDataWrapper(*init_configuration);
-      break;
-    }
-    CHAOS_CHECK_LIST_DONE(check_list_sub_service, "init", INIT_SM_PHASE_CREATE_DATA_STORAGE) {
-      //call init sequence
-      //call update param function
-      //initialize key data storage for device id
-      ACULAPP_ << "Create KeyDataStorage device:" << DatasetDB::getDeviceID();
-      key_data_storage.reset(DataManager::getInstance()->getKeyDataStorageNewInstanceForKey(DatasetDB::getDeviceID()));
-
-      ACULAPP_ << "Call KeyDataStorage init implementation for deviceID:" << DatasetDB::getDeviceID();
-      key_data_storage->init(init_configuration.get());
-      break;
+    
+    /*
+     return the CU name
+     */
+    const std::string& AbstractControlUnit::getCUInstance() {
+        return control_unit_instance;
+    };
+    
+    const std::string& AbstractControlUnit::getCUID() {
+        return control_unit_id;
     }
-  }
-  CHAOS_CHECK_LIST_END_SCAN_TO_DO(check_list_sub_service, "init")
-}
-
-void AbstractControlUnit::doStartRpCheckList() {
-  CHAOS_CHECK_LIST_START_SCAN_TO_DO(check_list_sub_service, "_start") {
-    CHAOS_CHECK_LIST_DONE(check_list_sub_service, "_start", START_RPC_PHASE_IMPLEMENTATION) {
-      start();
-      break;
-    }
-    CHAOS_CHECK_LIST_DONE(check_list_sub_service, "_start", START_RPC_PHASE_UNIT) {
-      unitStart();
-      break;
-    }
-    CHAOS_CHECK_LIST_DONE(check_list_sub_service, "_start", START_RPC_PHASE_RESTORE_ON_FIRST_START) {
-      try {
-        checkForRestoreOnInit();
-        check_list_sub_service.getSharedCheckList("_start")->removeElement(START_RPC_PHASE_RESTORE_ON_FIRST_START);
-      } catch (CException& ex) {
-        check_list_sub_service.getSharedCheckList("_start")->removeElement(START_RPC_PHASE_RESTORE_ON_FIRST_START);
-        throw;
-      }
-      break;
-    }
-  }
-  CHAOS_CHECK_LIST_END_SCAN_TO_DO(check_list_sub_service, "_start")
-}
-
-void AbstractControlUnit::doStartSMCheckList() {
-  CHAOS_CHECK_LIST_START_SCAN_TO_DO(check_list_sub_service, "start") {
-    CHAOS_CHECK_LIST_DONE(check_list_sub_service, "start", START_SM_PHASE_STAT_TIMER) {
-      //register timer for push statistic
-      chaos::common::async_central::AsyncCentralManager::getInstance()->addTimer(this, 0, chaos::common::constants::CUTimersTimeoutinMSec);
-      //get timestamp for first pushes metric acquisition
-      last_push_rate_grap_ts = TimingUtil::getTimeStamp();
-    }
-  }
-  CHAOS_CHECK_LIST_END_SCAN_TO_DO(check_list_sub_service, "start")
-}
-
-void AbstractControlUnit::redoInitRpCheckList(bool throw_exception) {
-  //rpc initialize service
-  CHAOS_CHECK_LIST_START_SCAN_DONE(check_list_sub_service, "_init") {
-    CHAOS_CHECK_LIST_REDO(check_list_sub_service, "_init", INIT_RPC_PHASE_CALL_INIT_STATE) {
-      //saftely deinititalize the abstract control unit
-      CHEK_IF_NEED_TO_THROW(throw_exception, deinit();)
-      break;
-    }
-    CHAOS_CHECK_LIST_REDO(check_list_sub_service, "_init", INIT_RPC_PHASE_INIT_SHARED_CACHE) {
-      ACULAPP_ << "Deallocate the user cache wrapper for:" + DatasetDB::getDeviceID();
-      if (attribute_shared_cache_wrapper) {
-        delete (attribute_shared_cache_wrapper);
-        attribute_shared_cache_wrapper = NULL;
-      }
-      break;
-    }
-    CHAOS_CHECK_LIST_REDO(check_list_sub_service, "_init", INIT_RPC_PHASE_COMPLETE_OUTPUT_ATTRIBUTE) {
-      break;
-    }
-    CHAOS_CHECK_LIST_REDO(check_list_sub_service, "_init", INIT_RPC_PHASE_COMPLETE_INPUT_ATTRIBUTE) {
-      break;
-    }
-    CHAOS_CHECK_LIST_REDO(check_list_sub_service, "_init", INIT_RPC_PHASE_INIT_SYSTEM_CACHE) {
-      break;
-    }
-    CHAOS_CHECK_LIST_REDO(check_list_sub_service, "_init", INIT_RPC_PHASE_CALL_UNIT_DEFINE_ATTRIBUTE) {
-      CHEK_IF_NEED_TO_THROW(throw_exception, unitDefineCustomAttribute();)
-      break;
-    }
-    CHAOS_CHECK_LIST_REDO(check_list_sub_service, "_init", INIT_RPC_PHASE_CREATE_FAST_ACCESS_CASCHE_VECTOR) {
-      //clear all cache sub_structure
-      CHEK_IF_NEED_TO_THROW(throw_exception,
-                            cache_output_attribute_vector.clear();
-                            cache_input_attribute_vector.clear();
-                            cache_custom_attribute_vector.clear();
-                            cache_system_attribute_vector.clear();)
-      break;
-    }
-    CHAOS_CHECK_LIST_REDO(check_list_sub_service, "_init", INIT_RPC_PHASE_CALL_UNIT_INIT) {
-      ACULDBG_ << "Deinit custom deinitialization for device:" << DatasetDB::getDeviceID();
-      CHEK_IF_NEED_TO_THROW(throw_exception, unitDeinit();)
-      break;
-    }
-    CHAOS_CHECK_LIST_REDO(check_list_sub_service, "_init", INIT_RPC_PHASE_UPDATE_CONFIGURATION) {
-      break;
-    }
-    CHAOS_CHECK_LIST_REDO(check_list_sub_service, "_init", INIT_RPC_PHASE_PUSH_DATASET) {
-      break;
-    }
-  }
-  CHAOS_CHECK_LIST_END_SCAN_DONE(check_list_sub_service, "_init")
-}
-
-void AbstractControlUnit::redoInitSMCheckList(bool throw_exception) {
-  CHAOS_CHECK_LIST_START_SCAN_DONE(check_list_sub_service, "init") {
-    CHAOS_CHECK_LIST_REDO(check_list_sub_service, "init", INIT_SM_PHASE_INIT_DB) {
-      break;
-    }
-    CHAOS_CHECK_LIST_REDO(check_list_sub_service, "init", INIT_SM_PHASE_CREATE_DATA_STORAGE) {
-      //remove key data storage
-      CHEK_IF_NEED_TO_THROW(throw_exception,
-                            if (key_data_storage.get()) {
-                              ACULDBG_ << "Delete data storage driver for device:" << DatasetDB::getDeviceID();
-                              key_data_storage->deinit();
-                              key_data_storage.reset();
-                            })
-      break;
-    }
-  }
-  CHAOS_CHECK_LIST_END_SCAN_DONE(check_list_sub_service, "init")
-}
-
-void AbstractControlUnit::redoStartRpCheckList(bool throw_exception) {
-  CHAOS_CHECK_LIST_START_SCAN_DONE(check_list_sub_service, "_start") {
-    CHAOS_CHECK_LIST_REDO(check_list_sub_service, "_start", START_RPC_PHASE_IMPLEMENTATION) {
-      CHEK_IF_NEED_TO_THROW(throw_exception, stop();)
-      break;
-    }
-    //unit sto need to go after the abstract cu has been stopped
-    CHAOS_CHECK_LIST_REDO(check_list_sub_service, "_start", START_RPC_PHASE_UNIT) {
-      CHEK_IF_NEED_TO_THROW(throw_exception, unitStop();)
-    }
-  }
-  CHAOS_CHECK_LIST_END_SCAN_DONE(check_list_sub_service, "_start")
-}
-
-void AbstractControlUnit::redoStartSMCheckList(bool throw_exception) {
-  CHAOS_CHECK_LIST_START_SCAN_DONE(check_list_sub_service, "start") {
-    CHAOS_CHECK_LIST_REDO(check_list_sub_service, "start", START_SM_PHASE_STAT_TIMER) {
-      //remove timer for push statistic
-      CHEK_IF_NEED_TO_THROW(throw_exception, chaos::common::async_central::AsyncCentralManager::getInstance()->removeTimer(this);)
-    }
-  }
-  CHAOS_CHECK_LIST_END_SCAN_DONE(check_list_sub_service, "start")
-}
-
-//----------------------------------------- protected initi/deinit method ------------------------------------------------
-#pragma mark RPC State Machine method
-CDWUniquePtr AbstractControlUnit::_init(CDWUniquePtr init_configuration) {
-  if (getServiceState() == CUStateKey::INIT) {
-    return CDWUniquePtr();
-  }
-
-  try {
-    if (getServiceState() == CUStateKey::RECOVERABLE_ERROR) {
-      LOG_AND_TROW_FORMATTED(ACULERR_, -2, "Recoverable error state need to be recovered for %1%", % __PRETTY_FUNCTION__)
+    
+    const std::string& AbstractControlUnit::getCUParam() {
+        return control_unit_param;
     }
-
-    //if(getServiceState() != CUStateKey::DEINIT) throw CException(-1, DatasetDB::getDeviceID()+" need to be in deinit", __PRETTY_FUNCTION__);
-    if (!attribute_value_shared_cache) {
-      LOG_AND_TROW_FORMATTED(ACULERR_, -3, "No Shared cache implementation found for %1%[%2%]", % DatasetDB::getDeviceID() % __PRETTY_FUNCTION__);
+    
+    const bool AbstractControlUnit::isCUParamInJson() {
+        return is_control_unit_json_param;
     }
-
-    if (!SWEService::initImplementation(this, "AbstractControlUnit", __PRETTY_FUNCTION__)) {
-      LOG_AND_TROW_FORMATTED(ACULERR_, -1, "Control Unit %1% can't be initilized [state mismatch]!", % DatasetDB::getDeviceID());
+    
+    const Json::Value& AbstractControlUnit::getCUParamJsonRootElement() {
+        return json_parameter_document;
     }
-
-  } catch (MetadataLoggingCException& ex) {
-    throw;
-  } catch (CException& ex) {
-    throw MetadataLoggingCException(getCUID(),
-                                    ex.errorCode,
-                                    ex.errorMessage,
-                                    ex.errorDomain);
-  }
-
-  try {
-    //update configuraiton and own it
-    this->init_configuration = MOVE(init_configuration);
-
-    HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
-                                                    NodeHealtDefinitionKey::NODE_HEALT_STATUS,
-                                                    NodeHealtDefinitionValue::NODE_HEALT_STATUS_INITING,
-                                                    true);
-    doInitRpCheckList();
-
-    //set healt to init
-    HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
-                                                    NodeHealtDefinitionKey::NODE_HEALT_STATUS,
-                                                    NodeHealtDefinitionValue::NODE_HEALT_STATUS_INIT,
-                                                    true);
-  } catch (MetadataLoggingCException& ex) {
-    SWEService::goInFatalError(this,
-                               ex,
-                               "AbstractControlUnit",
-                               __PRETTY_FUNCTION__);
-    throw;
-  } catch (CException& ex) {
-    MetadataLoggingCException loggable_exception(getCUID(),
-                                                 ex.errorCode,
-                                                 ex.errorMessage,
-                                                 ex.errorDomain);
-    //go in falta error
-    SWEService::goInFatalError(this,
-                               loggable_exception,
-                               "AbstractControlUnit",
-                               __PRETTY_FUNCTION__);
-    throw loggable_exception;
-  }
-  return CDWUniquePtr();
-}
-
-CDWUniquePtr AbstractControlUnit::_start(CDWUniquePtr startParam) {
-  if (getServiceState() == CUStateKey::START) {
-    return CDWUniquePtr();
-  }
-  try {
-    if (getServiceState() == CUStateKey::RECOVERABLE_ERROR) {
-      LOG_AND_TROW_FORMATTED(ACULERR_, -1, "Recoverable error state need to be recovered for %1%", % __PRETTY_FUNCTION__)
-    }
-    //call start method of the startable interface
-    if (!SWEService::startImplementation(this, "AbstractControlUnit", __PRETTY_FUNCTION__)) {
-      LOG_AND_TROW_FORMATTED(ACULERR_, -1, "Control Unit %1% can't be started [state mismatch]!", % DatasetDB::getDeviceID());
+    
+    const std::string& AbstractControlUnit::getCUType() {
+        return control_unit_type;
     }
-
-  } catch (MetadataLoggingCException& ex) {
-    throw;
-  } catch (CException& ex) {
-    throw MetadataLoggingCException(getCUID(),
-                                    ex.errorCode,
-                                    ex.errorMessage,
-                                    ex.errorDomain);
-  }
-
-  try {
-    HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
-                                                    NodeHealtDefinitionKey::NODE_HEALT_STATUS,
-                                                    NodeHealtDefinitionValue::NODE_HEALT_STATUS_STARTING,
-                                                    true);
-
-    doStartRpCheckList();
-
-    //set healt to start
-    HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
-                                                    NodeHealtDefinitionKey::NODE_HEALT_STATUS,
-                                                    NodeHealtDefinitionValue::NODE_HEALT_STATUS_START,
-                                                    true);
-  } catch (MetadataLoggingCException& ex) {
-    SWEService::goInFatalError(this,
-                               ex,
-                               "AbstractControlUnit",
-                               __PRETTY_FUNCTION__);
-    throw;
-  } catch (CException& ex) {
-    MetadataLoggingCException loggable_exception(getCUID(),
-                                                 ex.errorCode,
-                                                 ex.errorMessage,
-                                                 ex.errorDomain);
-    //go in falta error
-    SWEService::goInFatalError(this, loggable_exception, "AbstractControlUnit", __PRETTY_FUNCTION__);
-    throw loggable_exception;
-  }
-  return CDWUniquePtr();
-}
-
-CDWUniquePtr AbstractControlUnit::_stop(CDWUniquePtr stopParam) {
-  if (getServiceState() == CUStateKey::STOP) {
-    return CDWUniquePtr();
-  }
-  try {
-    /*
-         * stop transition is possible with recoverable error
-         *  if(getServiceState() == CUStateKey::RECOVERABLE_ERROR) {
-         LOG_AND_TROW_FORMATTED(ACULERR_, -1, "Recoverable error state need to be recovered for %1%", %__PRETTY_FUNCTION__)
-         }
-         */
-    //first we start the deinitializaiton of the implementation unit
-    if (!SWEService::stopImplementation(this, "AbstractControlUnit", __PRETTY_FUNCTION__)) {
-      LOG_AND_TROW_FORMATTED(ACULERR_, -1, "Control Unit %1% can't be stopped [state mismatch]!", % DatasetDB::getDeviceID());
-    }
-  } catch (MetadataLoggingCException& ex) {
-    SWEService::goInFatalError(this,
-                               ex,
-                               "AbstractControlUnit",
-                               __PRETTY_FUNCTION__);
-    throw;
-  } catch (CException& ex) {
-    throw MetadataLoggingCException(getCUID(),
-                                    ex.errorCode,
-                                    ex.errorMessage,
-                                    ex.errorDomain);
-  }
-
-  try {
-    //set healt to start
-    HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
-                                                    NodeHealtDefinitionKey::NODE_HEALT_STATUS,
-                                                    NodeHealtDefinitionValue::NODE_HEALT_STATUS_STOPING,
-                                                    true);
-    redoStartRpCheckList();
-
-    HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
-                                                    NodeHealtDefinitionKey::NODE_HEALT_STATUS,
-                                                    NodeHealtDefinitionValue::NODE_HEALT_STATUS_STOP,
-                                                    true);
-  } catch (MetadataLoggingCException& ex) {
-    SWEService::goInFatalError(this,
-                               ex,
-                               "AbstractControlUnit",
-                               __PRETTY_FUNCTION__);
-    throw;
-  } catch (CException& ex) {
-    MetadataLoggingCException loggable_exception(getCUID(),
-                                                 ex.errorCode,
-                                                 ex.errorMessage,
-                                                 ex.errorDomain);
-    //go in falta error
-    SWEService::goInFatalError(this, loggable_exception, "AbstractControlUnit", __PRETTY_FUNCTION__);
-    throw loggable_exception;
-  }
-
-  return CDWUniquePtr();
-}
-
-/*go
- deinit all datastorage
- */
-CDWUniquePtr AbstractControlUnit::_deinit(CDWUniquePtr deinitParam) {
-  if (getServiceState() == CUStateKey::DEINIT) {
-    return CDWUniquePtr();
-  }
-  try {
+    
     /*
-         * deinit transition is possible with recoverable error
-         *  if(getServiceState() == CUStateKey::RECOVERABLE_ERROR) {
-         LOG_AND_TROW_FORMATTED(ACULERR_, -1, "Recoverable error state need to be recovered for %1%", %__PRETTY_FUNCTION__)
-         }
-         */
-    if (!SWEService::deinitImplementation(this, "AbstractControlUnit", __PRETTY_FUNCTION__)) {
-      LOG_AND_TROW_FORMATTED(ACULERR_, -1, "Control Unit %1% can't be deinitilized [state mismatch]!", % DatasetDB::getDeviceID());
-    }
-  } catch (MetadataLoggingCException& ex) {
-    throw;
-  } catch (CException& ex) {
-    throw MetadataLoggingCException(getCUID(),
-                                    ex.errorCode,
-                                    ex.errorMessage,
-                                    ex.errorDomain);
-  }
-
-  //first we start the deinitializaiton of the implementation unit
-  try {
-    HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
-                                                    NodeHealtDefinitionKey::NODE_HEALT_STATUS,
-                                                    NodeHealtDefinitionValue::NODE_HEALT_STATUS_DEINITING,
-                                                    true);
-
-    redoInitRpCheckList();
-
-    //set healt to deinit
-    HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
-                                                    NodeHealtDefinitionKey::NODE_HEALT_STATUS,
-                                                    NodeHealtDefinitionValue::NODE_HEALT_STATUS_DEINIT,
-                                                    true);
-  } catch (MetadataLoggingCException& ex) {
-    SWEService::goInFatalError(this,
-                               ex,
-                               "AbstractControlUnit",
-                               __PRETTY_FUNCTION__);
-    throw;
-  } catch (CException& ex) {
-    MetadataLoggingCException loggable_exception(getCUID(),
-                                                 ex.errorCode,
-                                                 ex.errorMessage,
-                                                 ex.errorDomain);
-
-    //go in falta error
-    SWEService::goInFatalError(this, loggable_exception, "AbstractControlUnit", __PRETTY_FUNCTION__);
-    throw loggable_exception;
-  }
-
-  return CDWUniquePtr();
-}
-
-CDWUniquePtr AbstractControlUnit::_recover(CDWUniquePtr gdeinitParam) {
-  if (getServiceState() != CUStateKey::RECOVERABLE_ERROR) throw MetadataLoggingCException(getCUID(), -1, DatasetDB::getDeviceID() + " need to be recoverable errore in the way to be recoverable!", __PRETTY_FUNCTION__);
-
-  //first we start the deinitializaiton of the implementation unit
-  try {
-    if (SWEService::recoverError(this, "AbstractControlUnit", __PRETTY_FUNCTION__)) {
-    } else {
-    }
-  } catch (MetadataLoggingCException& ex) {
-    SWEService::goInFatalError(this,
-                               ex,
-                               "AbstractControlUnit",
-                               __PRETTY_FUNCTION__);
-    throw;
-  } catch (CException& ex) {
-    MetadataLoggingCException loggable_exception(getCUID(),
-                                                 ex.errorCode,
-                                                 ex.errorMessage,
-                                                 ex.errorDomain);
-    //go in falta error
-    SWEService::goInFatalError(this, loggable_exception, "AbstractControlUnit", __PRETTY_FUNCTION__);
-    throw loggable_exception;
-  }
-
-  return CDWUniquePtr();
-}
-
-//! fill cache with found dataset at the restore point
-void AbstractControlUnit::fillRestoreCacheWithDatasetFromTag(chaos::cu::data_manager::KeyDataStorageDomain domain,
-                                                             CDataWrapper&                      dataset,
-                                                             AbstractSharedDomainCache&         restore_cache) {
-  std::vector<std::string> dataset_key;
-  dataset.getAllKey(dataset_key);
-  for (std::vector<std::string>::iterator it = dataset_key.begin();
-       it != dataset_key.end();
-       it++) {
-    restore_cache.addAttribute((SharedCacheDomain)domain,
-                               *it,
-                               dataset.getVariantValue(*it));
-  }
-}
-
-void AbstractControlUnit::checkForRestoreOnInit() {
-  //now we can launch the restore the current input attrite, remeber that
-  //input attribute are composed by mds so the type of restore data(static conf or live) is manage at mds leve
-  //control unit in case off pply true need only to launch the restore on current input dataset set.
-  try {
-    ChaosUniquePtr<AttributeValueSharedCache> restore_cache(new AttributeValueSharedCache());
-    if (!restore_cache.get()) throw MetadataLoggingCException(getCUID(), -3, "failed to allocate restore cache", __PRETTY_FUNCTION__);
-
-    AttributeCache& ac_src = attribute_value_shared_cache->getSharedDomain(DOMAIN_INPUT);
-    AttributeCache& ac_dst = restore_cache->getSharedDomain(DOMAIN_INPUT);
-    ac_src.copyToAttributeCache(ac_dst);
-
-    //unitRestoreToSnapshot
-    if (unitRestoreToSnapshot(restore_cache.get())) {
-      metadataLogging(chaos::common::metadata_logging::StandardLoggingChannel::LogLevelInfo,
-                      "Restore to initilization value run successfully");
-    } else {
-      metadataLogging(chaos::common::metadata_logging::StandardLoggingChannel::LogLevelError,
-                      "Restore to initilization value has fault");
-
-      //input attribute already already updated
-    }
-  } catch (MetadataLoggingCException& ex) {
-    throw;
-  } catch (CException& ex) {
-    MetadataLoggingCException loggable_exception(getCUID(),
-                                                 ex.errorCode,
-                                                 ex.errorMessage,
-                                                 ex.errorDomain);
-
-    DECODE_CHAOS_EXCEPTION(loggable_exception);
-  }
-}
-
-/*!
- Restore the control unit to a precise tag
- */
-CDWUniquePtr AbstractControlUnit::_unitRestoreToSnapshot(CDWUniquePtr restoreParam) {
-  int err = 0;
-  //check
-  if (!restoreParam.get() || !restoreParam->hasKey(NodeDomainAndActionRPC::ACTION_NODE_RESTORE_PARAM_TAG)) return CDWUniquePtr();
-
-  if (getServiceState() != CUStateKey::START) {
-    throw MetadataLoggingCException(getCUID(), -1, "Control Unit restore can appen only in start state", __PRETTY_FUNCTION__);
-  }
-
-  if (!key_data_storage.get()) throw MetadataLoggingCException(getCUID(), -2, "Key data storage driver not allocated", __PRETTY_FUNCTION__);
-
-  ChaosSharedPtr<AttributeValueSharedCache> restore_cache(new AttributeValueSharedCache());
-  if (!restore_cache.get()) throw MetadataLoggingCException(getCUID(), -3, "failed to allocate restore cache", __PRETTY_FUNCTION__);
-
-  ChaosSharedPtr<CDataWrapper> dataset_at_tag;
-  //get tag alias
-  const std::string restore_snapshot_tag = restoreParam->getStringValue(NodeDomainAndActionRPC::ACTION_NODE_RESTORE_PARAM_TAG);
-
-  metadataLogging(chaos::common::metadata_logging::StandardLoggingChannel::LogLevelInfo,
-                  CHAOS_FORMAT("Start restoring snapshot tag for: %1%", % restore_snapshot_tag));
-
-  attribute_value_shared_cache->getAttributeValue(DOMAIN_SYSTEM, ControlUnitDatapackSystemKey::SETPOINT_TAG)->setStringValue(restore_snapshot_tag, true, true);
-  *attribute_value_shared_cache->getAttributeValue(DOMAIN_SYSTEM, ControlUnitDatapackSystemKey::SETPOINT_STATE)->getValuePtr<int32_t>() = ControlUnitNodeDefinitionType::SetpointRestoreStarted;  //start
-
-  attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM).markAllAsChanged();
-  pushSystemDataset();
-
-  //load snapshot to restore
-  if ((err = key_data_storage->loadRestorePoint(restore_snapshot_tag))) {
-    ACULERR_ << "Error loading dataset form snapshot tag: " << restore_snapshot_tag;
-    *attribute_value_shared_cache->getAttributeValue(DOMAIN_SYSTEM, ControlUnitDatapackSystemKey::SETPOINT_STATE)->getValuePtr<int32_t>() = ControlUnitNodeDefinitionType::SetpointErrorOnInit;  //error
-
-    attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM).markAllAsChanged();
-    pushSystemDataset();
-
-    throw MetadataLoggingCException(getCUID(), err, "Error loading dataset form snapshot", __PRETTY_FUNCTION__);
-  } else {
-    restore_cache->init(NULL);
-
-    for (int idx = 0; idx < 4; idx++) {
-      //dataset loading sucessfull
-      dataset_at_tag = key_data_storage->getDatasetFromRestorePoint(restore_snapshot_tag,
-                                                                    (KeyDataStorageDomain)idx);
-      if (dataset_at_tag.get()) {
-        ACULDBG_ << CHAOS_FORMAT("Dataset restored from tag %1% -> %2%", % restore_snapshot_tag % dataset_at_tag->getJSONString());
-        //fill cache with dataset key/value
-        fillRestoreCacheWithDatasetFromTag((KeyDataStorageDomain)idx,
-                                           *dataset_at_tag.get(),
-                                           *restore_cache.get());
-      }
-    }
-    *attribute_value_shared_cache->getAttributeValue(DOMAIN_SYSTEM, ControlUnitDatapackSystemKey::SETPOINT_STATE)->getValuePtr<int32_t>() = ControlUnitNodeDefinitionType::SetpointRestoreRunning;  //running
-    attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM).markAllAsChanged();
-    pushSystemDataset();
-
-    try {
-      //unitRestoreToSnapshot
-      if (unitRestoreToSnapshot(restore_cache.get())) {
-        metadataLogging(chaos::common::metadata_logging::StandardLoggingChannel::LogLevelInfo,
-                        CHAOS_FORMAT("Restore for %1% has been run successfully", % restore_snapshot_tag));
-        *attribute_value_shared_cache->getAttributeValue(DOMAIN_SYSTEM, ControlUnitDatapackSystemKey::SETPOINT_STATE)->getValuePtr<int32_t>() = ControlUnitNodeDefinitionType::SetpointRestoreReached;  //end
-        attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM).markAllAsChanged();
-        pushSystemDataset();
-
-      } else {
-        metadataLogging(chaos::common::metadata_logging::StandardLoggingChannel::LogLevelError,
-                        CHAOS_FORMAT("Restore for %1% has been faulted", % restore_snapshot_tag));
-
-        *attribute_value_shared_cache->getAttributeValue(DOMAIN_SYSTEM, ControlUnitDatapackSystemKey::SETPOINT_STATE)->getValuePtr<int32_t>() = ControlUnitNodeDefinitionType::SetpointErrorOnStart;  //error
-        attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM).markAllAsChanged();
-        pushSystemDataset();
-        //input dataset need to be update
-        AttributeCache& ac_src = restore_cache->getSharedDomain(DOMAIN_INPUT);
-        AttributeCache& ac_dst = attribute_value_shared_cache->getSharedDomain(DOMAIN_INPUT);
-        ac_src.copyToAttributeCache(ac_dst);
-      }
-    } catch (MetadataLoggingCException& ex) {
-      *attribute_value_shared_cache->getAttributeValue(DOMAIN_SYSTEM, ControlUnitDatapackSystemKey::SETPOINT_STATE)->getValuePtr<int32_t>() = ControlUnitNodeDefinitionType::SetpointErrorOnRunning;  //error
-      attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM).markAllAsChanged();
-      pushSystemDataset();
-      throw;
-    } catch (CException& ex) {
-      *attribute_value_shared_cache->getAttributeValue(DOMAIN_SYSTEM, ControlUnitDatapackSystemKey::SETPOINT_STATE)->getValuePtr<int32_t>() = ControlUnitNodeDefinitionType::SetpointErrorException;  //error
-      attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM).markAllAsChanged();
-      pushSystemDataset();
-      MetadataLoggingCException loggable_exception(getCUID(),
-                                                   ex.errorCode,
-                                                   ex.errorMessage,
-                                                   ex.errorDomain);
-
-      DECODE_CHAOS_EXCEPTION(loggable_exception);
+     fill the CDataWrapper with AbstractCU system configuration, this method
+     is called after getStartConfiguration directly by sandbox. in this method
+     are defined the action for the input element of the dataset
+     */
+    void AbstractControlUnit::_defineActionAndDataset(CDataWrapper& setup_configuration) {
+        vector<std::string> tempStringVector;
+        
+        if (control_unit_id.size()) {
+            setDeviceID(control_unit_id);
+        }
+        
+        //add the CU isntance, this can be redefinide by user in the unitDefineActionAndDataset method
+        //for let the CU have the same instance at every run
+        setup_configuration.addStringValue(NodeDefinitionKey::NODE_RPC_DOMAIN, control_unit_instance);
+        
+        //if we have a control key we attach it
+        setup_configuration.addStringValue("mds_control_key", control_key);
+        
+        //add the control unit type with semantonc type::subtype
+        setup_configuration.addStringValue(NodeDefinitionKey::NODE_TYPE, NodeType::NODE_TYPE_CONTROL_UNIT);
+        setup_configuration.addStringValue(NodeDefinitionKey::NODE_SUB_TYPE, control_unit_type);
+        //check if as been setuped a file for configuration
+        //LCU_ << "Check if as been setup a json file path to configura CU:" << CU_IDENTIFIER_C_STREAM;
+        //loadCDataWrapperForJsonFile(setup_configuration);
+        
+        //first call the setup abstract method used by the implementing CU to define action, dataset and other
+        //usefull value
+        unitDefineActionAndDataset();
+        
+        //call method to dinamically add other things to the dataset
+        _completeDatasetAttribute();
+        
+        //for now we need only to add custom action for expose to rpc
+        //input element of the dataset
+        AbstActionDescShrPtr
+        action_description = addActionDescritionInstance<AbstractControlUnit>(this,
+                                                                              &AbstractControlUnit::_setDatasetAttribute,
+                                                                              ControlUnitNodeDomainAndActionRPC::CONTROL_UNIT_APPLY_INPUT_DATASET_ATTRIBUTE_CHANGE_SET,
+                                                                              "method for set the input element for the dataset");
+        
+        //expose updateConfiguration Methdo to rpc
+        action_description = addActionDescritionInstance<AbstractControlUnit>(this,
+                                                                              &AbstractControlUnit::updateConfiguration,
+                                                                              NodeDomainAndActionRPC::ACTION_UPDATE_PROPERTY,
+                                                                              "Update control unit property");
+        
+        action_description = addActionDescritionInstance<AbstractControlUnit>(this,
+                                                                              &AbstractControlUnit::_init,
+                                                                              NodeDomainAndActionRPC::ACTION_NODE_INIT,
+                                                                              "Perform the control unit initialization");
+        
+        action_description = addActionDescritionInstance<AbstractControlUnit>(this,
+                                                                              &AbstractControlUnit::_deinit,
+                                                                              NodeDomainAndActionRPC::ACTION_NODE_DEINIT,
+                                                                              "Perform the control unit deinitialization");
+        action_description = addActionDescritionInstance<AbstractControlUnit>(this,
+                                                                              &AbstractControlUnit::_start,
+                                                                              NodeDomainAndActionRPC::ACTION_NODE_START,
+                                                                              "Start the control unit scheduling");
+        
+        action_description = addActionDescritionInstance<AbstractControlUnit>(this,
+                                                                              &AbstractControlUnit::_stop,
+                                                                              NodeDomainAndActionRPC::ACTION_NODE_STOP,
+                                                                              "Stop the control unit scheduling");
+        
+        action_description = addActionDescritionInstance<AbstractControlUnit>(this,
+                                                                              &AbstractControlUnit::_recover,
+                                                                              NodeDomainAndActionRPC::ACTION_NODE_RECOVER,
+                                                                              "Recovery a recoverable state, going to the last state");
+        
+        action_description = addActionDescritionInstance<AbstractControlUnit>(this,
+                                                                              &AbstractControlUnit::_unitRestoreToSnapshot,
+                                                                              NodeDomainAndActionRPC::ACTION_NODE_RESTORE,
+                                                                              "Restore contorl unit to a snapshot tag");
+        
+        action_description = addActionDescritionInstance<AbstractControlUnit>(this,
+                                                                              &AbstractControlUnit::_getState,
+                                                                              NodeDomainAndActionRPC::ACTION_NODE_GET_STATE,
+                                                                              "Get the state of the running control unit");
+        
+        action_description = addActionDescritionInstance<AbstractControlUnit>(this,
+                                                                              &AbstractControlUnit::_getInfo,
+                                                                              NodeDomainAndActionRPC::ACTION_CU_GET_INFO,
+                                                                              "Get the information about running control unit");
+        action_description = addActionDescritionInstance<AbstractControlUnit>(this,
+                                                                              &AbstractControlUnit::_submitStorageBurst,
+                                                                              ControlUnitNodeDomainAndActionRPC::ACTION_STORAGE_BURST,
+                                                                              "Execute a storage burst on control unit");
+        action_description->addParam(ControlUnitNodeDefinitionKey::CONTROL_UNIT_DATASET_HISTORY_BURST_TAG, DataType::TYPE_STRING, "Tag associated to the stored data during burst");
+        action_description->addParam(ControlUnitNodeDefinitionKey::CONTROL_UNIT_DATASET_HISTORY_BURST_TYPE, DataType::TYPE_INT32, "The type of burst");
+        action_description->addParam(ControlUnitNodeDefinitionKey::CONTROL_UNIT_DATASET_HISTORY_BURST_VALUE, DataType::TYPE_UNDEFINED, "The value of the burst is defined by the type");
+        
+        action_description = addActionDescritionInstance<AbstractControlUnit>(this,
+                                                                              &AbstractControlUnit::_datasetTagManagement,
+                                                                              ControlUnitNodeDomainAndActionRPC::ACTION_DATASET_TAG_MANAGEMENT,
+                                                                              "Execute a storage burst on control unit");
+        action_description->addParam(ControlUnitNodeDomainAndActionRPC::ACTION_DATASET_TAG_MANAGEMENT_ADD_LIST, DataType::TYPE_ACCESS_ARRAY, "List of tag to be added to the control unit dataset");
+        action_description->addParam(ControlUnitNodeDomainAndActionRPC::ACTION_DATASET_TAG_MANAGEMENT_REMOVE_LIST, DataType::TYPE_ACCESS_ARRAY, "List of tag to be removed to the control unit dataset");
+        //grab dataset description
+        DatasetDB::fillDataWrapperWithDataSetDescription(setup_configuration);
+        
+        //    //get action description
+        //    getActionDescrionsInDataWrapper(setup_configuration);
+        
+        //add property description
+        PropertyCollector::fillDescription("property", setup_configuration);
     }
-
-    //end
-    try {
-      restore_cache->deinit();
-    } catch (MetadataLoggingCException& ex) {
-      throw;
-    } catch (CException& ex) {
-      MetadataLoggingCException loggable_exception(getCUID(),
-                                                   ex.errorCode,
-                                                   ex.errorMessage,
-                                                   ex.errorDomain);
-      DECODE_CHAOS_EXCEPTION(loggable_exception);
-    } catch (...) {
-      ACULERR_ << "General error on deinit restore cache";
+    
+    void AbstractControlUnit::unitDefineDriver(std::vector<DrvRequestInfo>& neededDriver) {
+        for (ControlUnitDriverListIterator iter = control_unit_drivers.begin();
+             iter != control_unit_drivers.end();
+             iter++) {
+            //copy driver info to the system array reference
+            neededDriver.push_back(*iter);
+        }
     }
-
-    //! clear snapshoted dataset to free memeory
-    key_data_storage->clearRestorePoint(restore_snapshot_tag);
-  }
-  metadataLogging(chaos::common::metadata_logging::StandardLoggingChannel::LogLevelInfo,
-                  CHAOS_FORMAT("End restoring snapshot tag for: %1%", % restore_snapshot_tag));
-  return CDWUniquePtr();
-}
-
-/*
- Receive the event for set the dataset input element
- */
-CDWUniquePtr AbstractControlUnit::_setDatasetAttribute(CDWUniquePtr dataset_attribute_values) {
-  CDWUniquePtr result;
-  try {
-    if (!dataset_attribute_values.get()) {
-      throw MetadataLoggingCException(getCUID(), -1, "No Input parameter", __PRETTY_FUNCTION__);
-    }
-    if (SWEService::getServiceState() == CUStateKey::DEINIT) {
-      throw MetadataLoggingCException(getCUID(), -3, "The Control Unit is in deinit state", __PRETTY_FUNCTION__);
-    }
-    //send dataset attribute change pack to control unit implementation
-    result = setDatasetAttribute(MOVE(dataset_attribute_values));
-  } catch (CException& ex) {
-    throw;
-  }
-  return result;
-}
-#pragma mark State Machine method
-// Startable Service method
-void AbstractControlUnit::init(void* init_data) {
-  //allocate metadata loggin channel for alarm
-  alarm_logging_channel = (AlarmLoggingChannel*)MetadataLoggingManager::getInstance()->getChannel("AlarmLoggingChannel");
-  if (alarm_logging_channel == NULL) {
-    LOG_AND_TROW(ACULERR_, -1, "Alarm logging channel not found");
-  }
-
-  standard_logging_channel = (StandardLoggingChannel*)MetadataLoggingManager::getInstance()->getChannel("StandardLoggingChannel");
-  if (standard_logging_channel == NULL) {
-    LOG_AND_TROW(ACULERR_, -2, "Standard logging channel not found");
-  }
-  standard_logging_channel->setLogLevel(common::metadata_logging::StandardLoggingChannel::LogLevelInfo);
-  //the init of the implementation unit goes after the infrastructure one
-  doInitSMCheckList();
-}
-
-// Startable Service method
-void AbstractControlUnit::start() {
-  doStartSMCheckList();
-}
-
-// Startable Service method
-void AbstractControlUnit::stop() {
-  redoStartSMCheckList();
-}
-
-// Startable Service method
-void AbstractControlUnit::deinit() {
-  redoInitSMCheckList();
-  if (alarm_logging_channel) {
-    MetadataLoggingManager::getInstance()->releaseChannel(alarm_logging_channel);
-    alarm_logging_channel = NULL;
-  }
-
-  if (standard_logging_channel) {
-    MetadataLoggingManager::getInstance()->releaseChannel(standard_logging_channel);
-    standard_logging_channel = NULL;
-  }
-}
-
-//! State machine is gone into recoverable error
-void AbstractControlUnit::recoverableErrorFromState(int last_state, chaos::CException& ex) {
-  ACULERR_ << "recoverableErrorFromState with state:" << last_state;
-
-  //update healt tstatus to report recoverable error
-  HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
-                                                  NodeHealtDefinitionKey::NODE_HEALT_STATUS,
-                                                  NodeHealtDefinitionValue::NODE_HEALT_STATUS_RERROR,
-                                                  false);
-  HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
-                                                  NodeHealtDefinitionKey::NODE_HEALT_LAST_ERROR_CODE,
-                                                  ex.errorCode,
-                                                  false);
-  HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
-                                                  NodeHealtDefinitionKey::NODE_HEALT_LAST_ERROR_MESSAGE,
-                                                  ex.errorMessage,
-                                                  false);
-  HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
-                                                  NodeHealtDefinitionKey::NODE_HEALT_LAST_ERROR_DOMAIN,
-                                                  ex.errorDomain,
-                                                  true);
-  //we stop the run action
-  CHAOS_NOT_THROW(stop();)
-}
-
-//! State machine is gone into recoverable error
-bool AbstractControlUnit::beforeRecoverErrorFromState(int last_state) {
-  ACULERR_ << "beforeRecoverErrorFromState with state:" << last_state;
-  std::string last_state_str;
-  switch (last_state) {
-    case CUStateKey::INIT:
-      last_state_str = NodeHealtDefinitionValue::NODE_HEALT_STATUS_INIT;
-      break;
-    case CUStateKey::DEINIT:
-      last_state_str = NodeHealtDefinitionValue::NODE_HEALT_STATUS_DEINIT;
-      break;
-    case CUStateKey::START:
-      last_state_str = NodeHealtDefinitionValue::NODE_HEALT_STATUS_START;
-      break;
-    case CUStateKey::STOP:
-      last_state_str = NodeHealtDefinitionValue::NODE_HEALT_STATUS_STOP;
-      break;
-  }
-  HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
-                                                  NodeHealtDefinitionKey::NODE_HEALT_STATUS,
-                                                  last_state_str,
-                                                  false);
-  HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
-                                                  NodeHealtDefinitionKey::NODE_HEALT_LAST_ERROR_CODE,
-                                                  0,
-                                                  false);
-  HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
-                                                  NodeHealtDefinitionKey::NODE_HEALT_LAST_ERROR_MESSAGE,
-                                                  "",
-                                                  false);
-  HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
-                                                  NodeHealtDefinitionKey::NODE_HEALT_LAST_ERROR_DOMAIN,
-                                                  "",
-                                                  true);
-  //restart the cotnrol unit
-  CHAOS_NOT_THROW(start();)
-  return true;
-}
-
-//! State machine is gone into recoverable error
-void AbstractControlUnit::recoveredToState(int last_state) {
-  ACULERR_ << "recoveredToState with state:" << last_state;
-}
-
-//! State machine is gone into an unrecoverable error
-void AbstractControlUnit::fatalErrorFromState(int last_state, chaos::CException& ex) {
-  ACULERR_ << "fatalErrorFromState with state:" << last_state;
-  switch (last_state) {
-    case CUStateKey::INIT:
-      //deinit
-      //CHAOS_NOT_THROW(redoInitSMCheckList(false);)
-      deinit();
-      CHAOS_NOT_THROW(redoInitRpCheckList(false);)
-      break;
-    case CUStateKey::DEINIT:
-
-      break;
-    case CUStateKey::START:
-      //stop
-      //CHAOS_NOT_THROW(redoStartSMCheckList(false);)
-      stop();
-      CHAOS_NOT_THROW(redoStartRpCheckList(false);)
-      //deinit
-      //CHAOS_NOT_THROW(redoInitSMCheckList(false);)
-      deinit();
-      CHAOS_NOT_THROW(redoInitRpCheckList(false);)
-      break;
-    case CUStateKey::STOP:
-      break;
-  }  //update healt tstatus to report recoverable error
-  HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
-                                                  NodeHealtDefinitionKey::NODE_HEALT_STATUS,
-                                                  NodeHealtDefinitionValue::NODE_HEALT_STATUS_FERROR,
-                                                  false);
-  HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
-                                                  NodeHealtDefinitionKey::NODE_HEALT_LAST_ERROR_CODE,
-                                                  ex.errorCode,
-                                                  false);
-  HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
-                                                  NodeHealtDefinitionKey::NODE_HEALT_LAST_ERROR_MESSAGE,
-                                                  ex.errorMessage,
-                                                  false);
-  HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
-                                                  NodeHealtDefinitionKey::NODE_HEALT_LAST_ERROR_DOMAIN,
-                                                  ex.errorDomain,
-                                                  true);
-}
-
-void AbstractControlUnit::fillCachedValueVector(AttributeCache&               attribute_cache,
-                                                std::vector<AttributeValue*>& cached_value) {
-  for (int idx = 0;
-       idx < attribute_cache.getNumberOfAttributes();
-       idx++) {
-    cached_value.push_back(attribute_cache.getValueSettingForIndex(idx));
-  }
-}
-
-void AbstractControlUnit::initAttributeOnSharedAttributeCache(SharedCacheDomain         domain,
-                                                              std::vector<std::string>& attribute_names) {
-  //add input attribute to shared setting
-  CHAOS_ASSERT(attribute_value_shared_cache)
-  RangeValueInfo  attributeInfo;
-  AttributeCache& attribute_setting = attribute_value_shared_cache->getSharedDomain(domain);
-
-  for (int idx = 0;
-       idx < attribute_names.size();
-       idx++) {
-    attributeInfo.reset();
-
-    // retrive the attribute description from the device database
-    DatasetDB::getAttributeRangeValueInfo(attribute_names[idx], attributeInfo);
-
-    // add the attribute to the shared setting object
-    attribute_setting.addAttribute(attribute_names[idx], attributeInfo.maxSize, attributeInfo.valueType, attributeInfo.binType);
-
-    if (!attributeInfo.defaultValue.size()) continue;
-    
-    //setting value using index (the index into the sharedAttributeSetting are sequencial to the inserted order)
-    try {
-      switch (attributeInfo.valueType) {
-        case DataType::TYPE_BOOLEAN: {
-          bool val = boost::lexical_cast<bool>(attributeInfo.defaultValue);
-          attribute_setting.setValueForAttribute(idx, &val, sizeof(bool));
-          ACULDBG_ << "Init attribute:" << attribute_names[idx]<<" to:"<<val;
-          break;
-        }
-        case DataType::TYPE_DOUBLE: {
-          double val = boost::lexical_cast<double>(attributeInfo.defaultValue);
-          attribute_setting.setValueForAttribute(idx, &val, sizeof(double));
-          ACULDBG_ << "Init attribute:" << attribute_names[idx]<<" to:"<<val;
-          break;
-        }
-        case DataType::TYPE_INT32: {
-          int32_t val = strtoul(attributeInfo.defaultValue.c_str(), 0, 0);  //boost::lexical_cast<int32_t>(attributeInfo.defaultValue);
-          attribute_setting.setValueForAttribute(idx, &val, sizeof(int32_t));
-          ACULDBG_ << "Init attribute:" << attribute_names[idx]<<" to:"<<val;
-          break;
-        }
-        case DataType::TYPE_INT64: {
-          int64_t val = strtoll(attributeInfo.defaultValue.c_str(), 0, 0);  //boost::lexical_cast<int64_t>(attributeInfo.defaultValue);
-          attribute_setting.setValueForAttribute(idx, &val, sizeof(int64_t));
-          ACULDBG_ << "Init attribute:" << attribute_names[idx]<<" to:"<<val;
-          break;
-        }
-        case DataType::TYPE_CLUSTER: {
-          CDataWrapper tmp;
-          tmp.setSerializedJsonData(attributeInfo.defaultValue.c_str());
-          attribute_setting.setValueForAttribute(idx, tmp);
-          ACULDBG_ << "Init attribute:" << attribute_names[idx]<<" to:"<<attributeInfo.defaultValue.c_str();
-        }
-        case DataType::TYPE_STRING: {
-          const char* val = attributeInfo.defaultValue.c_str();
-          attribute_setting.setValueForAttribute(idx, val, (uint32_t)attributeInfo.defaultValue.size());
-           ACULDBG_ << "Init attribute:" << attribute_names[idx]<<" to:"<<val;
-          break;
-        }
-        case DataType::TYPE_BYTEARRAY: {
-          ACULDBG_ << "Binary default setting has not been yet managed";
-          break;
-        }
-        default:
-          break;
-      }
-    } catch (boost::bad_lexical_cast const& e) {
-      ACULERR_ << e.what();
-    }
-  }
-}
-
-void AbstractControlUnit::completeOutputAttribute() {
-  ACULDBG_ << "Complete the shared cache output attribute";
-  AttributeCache& domain_attribute_setting = attribute_value_shared_cache->getSharedDomain(DOMAIN_OUTPUT);
-
-  //add timestamp
-  domain_attribute_setting.addAttribute(DataPackCommonKey::DPCK_TIMESTAMP, sizeof(uint64_t), DataType::TYPE_INT64);
-  timestamp_acq_cached_value = domain_attribute_setting.getValueSettingForIndex(domain_attribute_setting.getIndexForName(DataPackCommonKey::DPCK_TIMESTAMP));
-
-  domain_attribute_setting.addAttribute(DataPackCommonKey::DPCK_HIGH_RESOLUTION_TIMESTAMP, sizeof(uint64_t), DataType::TYPE_INT64);
-  timestamp_hw_acq_cached_value = domain_attribute_setting.getValueSettingForIndex(domain_attribute_setting.getIndexForName(DataPackCommonKey::DPCK_HIGH_RESOLUTION_TIMESTAMP));
-}
-
-void AbstractControlUnit::completeInputAttribute() {
-}
-
-AbstractSharedDomainCache* AbstractControlUnit::_getAttributeCache() {
-  return attribute_value_shared_cache;
-}
-
-void AbstractControlUnit::initSystemAttributeOnSharedAttributeCache() {
-  AttributeCache& domain_attribute_setting = attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM);
-
-  //add schedule time
-  ACULDBG_ << "Adding system attribute on shared cache";
-  domain_attribute_setting.addAttribute(ControlUnitDatapackSystemKey::THREAD_SCHEDULE_DELAY, 0, DataType::TYPE_INT64);
-  thread_schedule_daly_cached_value = domain_attribute_setting.getValueSettingForIndex(domain_attribute_setting.getIndexForName(ControlUnitDatapackSystemKey::THREAD_SCHEDULE_DELAY));
-
-  //add busy state
-  domain_attribute_setting.addAttribute("busy", 0, DataType::TYPE_BOOLEAN);
-
-  //add bypass state
-  domain_attribute_setting.addAttribute(ControlUnitDatapackSystemKey::BYPASS_STATE, 0, DataType::TYPE_BOOLEAN);
-
-  //add AlarmCU state
-  domain_attribute_setting.addAttribute(chaos::ControlUnitDatapackSystemKey::CU_ALRM_LEVEL, 0, DataType::TYPE_INT32);
-
-  //add AlarmDev state
-  domain_attribute_setting.addAttribute(chaos::ControlUnitDatapackSystemKey::DEV_ALRM_LEVEL, 0, DataType::TYPE_INT32);
-
-  //add burst operation state
-  domain_attribute_setting.addAttribute(ControlUnitDatapackSystemKey::BURST_STATE, 0, DataType::TYPE_BOOLEAN);
-
-  //add burst operation tag
-  domain_attribute_setting.addAttribute(ControlUnitDatapackSystemKey::BURST_TAG, 0, DataType::TYPE_STRING);
-
-  //add setpoint operation state
-  domain_attribute_setting.addAttribute(ControlUnitDatapackSystemKey::SETPOINT_STATE, 0, DataType::TYPE_INT32);
-
-  //add setpoint operation tag
-  domain_attribute_setting.addAttribute(ControlUnitDatapackSystemKey::SETPOINT_TAG, 0, DataType::TYPE_STRING);
-
-  //add storage type
-  domain_attribute_setting.addAttribute(DataServiceNodeDefinitionKey::DS_STORAGE_TYPE, 0, DataType::TYPE_INT32);
-
-  //add live time
-  domain_attribute_setting.addAttribute(DataServiceNodeDefinitionKey::DS_STORAGE_LIVE_TIME, 0, DataType::TYPE_INT64);
-
-  //add history time
-  domain_attribute_setting.addAttribute(DataServiceNodeDefinitionKey::DS_STORAGE_HISTORY_TIME, 0, DataType::TYPE_INT64);
-
-  //add history time
-  domain_attribute_setting.addAttribute(DataServiceNodeDefinitionKey::DS_STORAGE_HISTORY_TIME, 0, DataType::TYPE_INT64);
-
-  //add unit type
-  domain_attribute_setting.addAttribute(DataPackSystemKey::DP_SYS_UNIT_TYPE, (uint32_t)control_unit_type.size(), DataType::TYPE_STRING);
-  char* str_ptr = domain_attribute_setting.getValueSettingForIndex(domain_attribute_setting.getIndexForName(DataPackSystemKey::DP_SYS_UNIT_TYPE))->getValuePtr<char>();
-  strncpy(str_ptr, control_unit_type.c_str(), control_unit_type.size());
-}
-
-/*
- Get the current control unit state
- */
-CDWUniquePtr AbstractControlUnit::_getState(CDWUniquePtr getStatedParam) {
-  CreateNewDataWrapper(result, );
-  result->addInt32Value(CUStateKey::CONTROL_UNIT_STATE, static_cast<CUStateKey::ControlUnitState>(SWEService::getServiceState()));
-  return result;
-}
-
-CDWUniquePtr AbstractControlUnit::_submitStorageBurst(CDWUniquePtr data) {
-  common::data::structured::DatasetBurstSDWrapper db_sdw;
-  db_sdw.deserialize(data.get());
-  DatasetBurstShrdPtr burst = ChaosMakeSharedPtr<DatasetBurst>(db_sdw());
-
-  if (burst->type == chaos::ControlUnitNodeDefinitionType::DSStorageBurstTypeUndefined) {
-    ACULERR_ << CHAOS_FORMAT("The type is mandatory for burst %1%", % data->getJSONString());
-    return CDWUniquePtr();
-  }
-  if (!burst->value.isValid()) {
-    ACULERR_ << CHAOS_FORMAT("The value is mandatory for burst %1%", % data->getJSONString());
-    return CDWUniquePtr();
-  }
-  ACULDBG_ << "Enabling burst:" << data->getCompliantJSONString();
-  LQueueBurstWriteLock wl = burst_queue.getWriteLockObject();
-  burst_queue().push(burst);
-  return CDWUniquePtr();
-}
-
-CDWUniquePtr AbstractControlUnit::_datasetTagManagement(CDWUniquePtr data) {
-  CHECK_ASSERTION_THROW_AND_LOG(data.get() != NULL, ACULERR_, -1, "No parameter found");
-  if (data->hasKey(ControlUnitNodeDomainAndActionRPC::ACTION_DATASET_TAG_MANAGEMENT_ADD_LIST)) {
-    CHECK_KEY_THROW_AND_LOG(data,
-                            ControlUnitNodeDomainAndActionRPC::ACTION_DATASET_TAG_MANAGEMENT_ADD_LIST,
-                            ACULERR_,
-                            -2,
-                            CHAOS_FORMAT("The key %1% need to be a vector", % ControlUnitNodeDomainAndActionRPC::ACTION_DATASET_TAG_MANAGEMENT_ADD_LIST));
-    ChaosStringSet                 ss;
-    CMultiTypeDataArrayWrapperSPtr vec = data->getVectorValue(ControlUnitNodeDomainAndActionRPC::ACTION_DATASET_TAG_MANAGEMENT_REMOVE_LIST);
-    for (int idx = 0; idx < vec->size(); idx++) {
-      if (vec->isStringElementAtIndex(idx)) {
-        ss.insert(vec->getStringElementAtIndex(idx));
-      }
-    }
-    key_data_storage->addTag(ss);
-  }
-
-  if (data->hasKey(ControlUnitNodeDomainAndActionRPC::ACTION_DATASET_TAG_MANAGEMENT_REMOVE_LIST)) {
-    CHECK_KEY_THROW_AND_LOG(data,
-                            ControlUnitNodeDomainAndActionRPC::ACTION_DATASET_TAG_MANAGEMENT_REMOVE_LIST,
-                            ACULERR_,
-                            -3,
-                            CHAOS_FORMAT("The key %1% need to be a vector", % ControlUnitNodeDomainAndActionRPC::ACTION_DATASET_TAG_MANAGEMENT_REMOVE_LIST));
-    ChaosStringSet                 ss;
-    CMultiTypeDataArrayWrapperSPtr vec = data->getVectorValue(ControlUnitNodeDomainAndActionRPC::ACTION_DATASET_TAG_MANAGEMENT_REMOVE_LIST);
-    for (int idx = 0; idx < vec->size(); idx++) {
-      if (vec->isStringElementAtIndex(idx)) {
-        ss.insert(vec->getStringElementAtIndex(idx));
-      }
-    }
-    key_data_storage->removeTag(ss);
-  }
-
-  return CDWUniquePtr();
-}
-
-/*
- Get the current control unit state
- */
-CDWUniquePtr AbstractControlUnit::_getInfo(CDWUniquePtr getStatedParam) {
-  CreateNewDataWrapper(stateResult, );
-  //set the string representing the type of the control unit
-  stateResult->addStringValue(NodeDefinitionKey::NODE_TYPE, NodeType::NODE_TYPE_CONTROL_UNIT);
-  stateResult->addStringValue(NodeDefinitionKey::NODE_SUB_TYPE, control_unit_type);
-  return stateResult;
-}
-
-void AbstractControlUnit::_updateAcquistionTimestamp(uint64_t alternative_ts) {
-  *timestamp_acq_cached_value->getValuePtr<uint64_t>() = alternative_ts / 1000;
-  if (!use_custom_high_resolution_timestamp) {
-    *timestamp_hw_acq_cached_value->getValuePtr<uint64_t>() = alternative_ts;
-  }
-}
-
-void AbstractControlUnit::useCustomHigResolutionTimestamp(bool _use_custom_high_resolution_timestamp) {
-  use_custom_high_resolution_timestamp = _use_custom_high_resolution_timestamp;
-}
-
-void AbstractControlUnit::setHigResolutionAcquistionTimestamp(uint64_t high_resolution_timestamp) {
-  if (use_custom_high_resolution_timestamp) {
-    *timestamp_hw_acq_cached_value->getValuePtr<uint64_t>() = high_resolution_timestamp;
-  }
-}
-
-void AbstractControlUnit::_updateRunScheduleDelay(uint64_t new_scehdule_delay) {
-  if (*thread_schedule_daly_cached_value->getValuePtr<uint64_t>() == new_scehdule_delay) return;
-  //we need to update the value
-  *thread_schedule_daly_cached_value->getValuePtr<uint64_t>() = new_scehdule_delay;
-  thread_schedule_daly_cached_value->markAsChanged();
-}
-
-//!timer for update push metric
-void AbstractControlUnit::_updatePushRateMetric() {
-  uint64_t rate_acq_ts    = TimingUtil::getTimeStamp();
-  double   time_offset    = (double(rate_acq_ts - last_push_rate_grap_ts)) / 1000.0;     //time in seconds
-  double   output_ds_rate = (time_offset > 0) ? push_dataset_counter / time_offset : 0;  //rate in seconds
-  int32_t   output_size_rate = (push_dataset_counter > 0) ? push_dataset_size / push_dataset_counter : 0;  //rate in seconds
-
-  HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
-                                                  ControlUnitHealtDefinitionValue::CU_HEALT_OUTPUT_DATASET_PUSH_RATE,
-                                                  output_ds_rate);
-  HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
-                                                  ControlUnitHealtDefinitionValue::CU_HEALT_OUTPUT_DATASET_PUSH_SIZE,
-                                                  output_size_rate);
-
-  //keep track of acquire timestamp
-  last_push_rate_grap_ts = rate_acq_ts;
-  //reset pushe count
-  push_dataset_counter = 0;
-  push_dataset_size=0;
-}
-
-//!put abstract control unit state machine in recoverable error
-void AbstractControlUnit::_goInRecoverableError(chaos::CException recoverable_exception) {
-  //change state machine
-  if (SWEService::goInRecoverableError(this, recoverable_exception, "RTAbstractControlUnit", __PRETTY_FUNCTION__)) {
-    //update healt the status to report recoverable error
-  }
-}
-
-//!put abstract control unit state machine in fatal error
-void AbstractControlUnit::_goInFatalError(chaos::CException recoverable_exception) {
-  //change state machine
-  if (SWEService::goInFatalError(this, recoverable_exception, "RTAbstractControlUnit", __PRETTY_FUNCTION__)) {
-  }
-}
-
-void AbstractControlUnit::_completeDatasetAttribute() {
-  //add global alarm checn
-  /*
-    DatasetDB::addAttributeToDataSet(stateVariableEnumToName(StateVariableTypeAlarmCU),
-                                     "Activated when some warning has been issued",
-                                     DataType::TYPE_INT32,
-                                     DataType::Output);
-    DatasetDB::addAttributeToDataSet(stateVariableEnumToName(StateVariableTypeAlarmDEV),
-                                     "Activated when some alarm has been issued",
-                                     DataType::TYPE_INT32,
-                                     DataType::Output);
-    */
-}
-
-void AbstractControlUnit::_setBypassState(bool bypass_stage,
-                                          bool high_priority) {
-  DrvMsg cmd;
-  cmd.opcode = bypass_stage ? OpcodeType::OP_SET_BYPASS : OpcodeType::OP_CLEAR_BYPASS;
-  //broadcast bypass to all driver instances allocated by control unit
-  for (VInstantitedDriverIterator it  = accessor_instances.begin(),
-                                  end = accessor_instances.end();
-       it != end;
-       it++) {
-    (*it)->send(&cmd, (high_priority ? 1000 : 0));
-  }
-  //update dateset
-  *attribute_value_shared_cache->getAttributeValue(DOMAIN_SYSTEM, ControlUnitDatapackSystemKey::BYPASS_STATE)->getValuePtr<bool>() = bypass_stage;
-}
-
-//!handler calledfor restor a control unit to a determinate point
-bool AbstractControlUnit::unitRestoreToSnapshot(AbstractSharedDomainCache* const snapshot_cache) {
-  return true;
-}
-
-//! this andler is called befor the input attribute will be updated
-void AbstractControlUnit::unitInputAttributePreChangeHandler() {}
-
-//! attribute change handler
-/*!
- the handle is fired after the input attribute cache as been update triggere
- by the rpc request for attribute change.
- */
-void AbstractControlUnit::unitInputAttributeChangedHandler() {}
-
-#define CHECK_FOR_RANGE_VALUE(t, v, attr_name)                                                                            \
-  t max, min;                                                                                                             \
-  if (attributeInfo.maxRange.compare(0, 2, "0x") == 0) {                                                                  \
-    max = strtoll(attributeInfo.maxRange.c_str(), 0, 0);                                                                  \
-  } else {                                                                                                                \
-    max = attributeInfo.maxRange.size() ? boost::lexical_cast<t>(attributeInfo.maxRange) : std::numeric_limits<t>::max(); \
-  }                                                                                                                       \
-  if (attributeInfo.minRange.compare(0, 2, "0x") == 0) {                                                                  \
-    min = strtoll(attributeInfo.minRange.c_str(), 0, 0);                                                                  \
-  } else {                                                                                                                \
-    min = attributeInfo.minRange.size() ? boost::lexical_cast<t>(attributeInfo.minRange) : std::numeric_limits<t>::min(); \
-  }                                                                                                                       \
-  if (v < min || v > max) throw MetadataLoggingCException(getCUID(), -1, boost::str(boost::format("Invalid value (%1%) [Min:%2% Max:%3%] for attribute %4%") % v % attributeInfo.minRange % attributeInfo.maxRange % attr_name).c_str(), __PRETTY_FUNCTION__);
-
-#define CHECK_FOR_STRING_RANGE_VALUE(v, attr_name)                                                                                                                                                                                                                                                      \
-  if (attributeInfo.minRange.size() && v < attributeInfo.minRange) throw MetadataLoggingCException(getCUID(), -1, boost::str(boost::format("Invalid value (%1%) [max:%2% Min:%3%] for attribute %4%") % v % attr_name % attributeInfo.minRange % attributeInfo.maxRange).c_str(), __PRETTY_FUNCTION__); \
-  if (attributeInfo.maxRange.size() && v > attributeInfo.maxRange) throw MetadataLoggingCException(getCUID(), -1, boost::str(boost::format("Invalid value (%1%) [max:%2% Min:%3%] for attribute %4%") % v % attr_name % attributeInfo.minRange % attributeInfo.maxRange).c_str(), __PRETTY_FUNCTION__);
-
-CDWUniquePtr AbstractControlUnit::setDatasetAttribute(CDWUniquePtr dataset_attribute_values) {
-  CHAOS_ASSERT(dataset_attribute_values.get())
-  ChaosSharedPtr<SharedCacheLockDomain> w_lock = attribute_value_shared_cache->getLockOnDomain(DOMAIN_INPUT, true);
-  w_lock->lock();
-
-  RangeValueInfo           attributeInfo;
-  std::vector<std::string> in_attribute_name;
-
-  try {
-    //call pre handler
-    unitInputAttributePreChangeHandler();
-
-    //first call attribute handler
-    dataset_attribute_manager.executeHandlers(dataset_attribute_values.get());
-
-    //get all input attribute name for input and bidirectional directions
-    getDatasetAttributesName(DataType::Input, in_attribute_name);
-    getDatasetAttributesName(DataType::Bidirectional, in_attribute_name);
-    attribute_value_shared_cache->getAttributeNames(DOMAIN_CUSTOM,in_attribute_name);
-    if (dataset_attribute_values->hasKey(NodeDefinitionKey::NODE_UNIQUE_ID)) {
-      //get the contrl unit id
-      std::string node_id = dataset_attribute_values->getStringValue(NodeDefinitionKey::NODE_UNIQUE_ID);
-      //compare the message device id and the local
-      for (std::vector<std::string>::iterator iter = in_attribute_name.begin();
-           iter != in_attribute_name.end();
-           iter++) {
-        //execute attribute handler
-        const char* attr_name = iter->c_str();
-
-        //check if the attribute name is present
-        if (dataset_attribute_values->hasKey(attr_name)) {
-          //check if attribute has been accepted
-          if (dataset_attribute_manager.getHandlerResult(*iter) == false) continue;
-
-          AttributeValue* attribute_cache_value = attribute_value_shared_cache->getAttributeValue(DOMAIN_INPUT, iter->c_str());
-
-          //get attribute info
-          getAttributeRangeValueInfo(*iter, attributeInfo);
-
-          //call handler
-          switch (attribute_cache_value->type) {
-            case DataType::TYPE_BOOLEAN: {
-              bool bv = dataset_attribute_values->getBoolValue(attr_name);
-              attribute_cache_value->setValue(&bv, sizeof(bool));
-              break;
+    
+    void AbstractControlUnit::unitDefineCustomAttribute() {
+    }
+    
+    void AbstractControlUnit::_undefineActionAndDataset() {
+        ACULDBG_ << "Remove Action Description";
+        unitUndefineActionAndDataset();
+    }
+    
+    void AbstractControlUnit::unitUndefineActionAndDataset() {
+    }
+    
+    //! Get all managem declare action instance
+    void AbstractControlUnit::_getDeclareActionInstance(std::vector<const chaos::DeclareAction*>& declareActionInstance) {
+        declareActionInstance.push_back(this);
+    }
+    
+    //----------------------------------------- checklist method ------------------------------------------------
+#pragma mark checklist method
+    void         AbstractControlUnit::doInitRpCheckList() {
+        std::vector<std::string> attribute_names;
+        //rpc initialize service
+        CHAOS_CHECK_LIST_START_SCAN_TO_DO(check_list_sub_service, "_init") {
+            CHAOS_CHECK_LIST_DONE(check_list_sub_service, "_init", INIT_RPC_PHASE_CALL_INIT_STATE) {
+                //call init sequence
+                init(NULL);
+                break;
             }
-            case DataType::TYPE_INT32: {
-              int32_t i32v = dataset_attribute_values->getInt32Value(attr_name);
-              CHECK_FOR_RANGE_VALUE(int32_t, i32v, attr_name)
-              attribute_cache_value->setValue(&i32v, sizeof(int32_t));
-              break;
+            CHAOS_CHECK_LIST_DONE(check_list_sub_service, "_init", INIT_RPC_PHASE_INIT_SHARED_CACHE) {
+                ACULAPP_ << "Allocate the user cache wrapper for:" + DatasetDB::getDeviceID();
+                attribute_shared_cache_wrapper = new AttributeSharedCacheWrapper(attribute_value_shared_cache);
+                
+                ACULAPP_ << "Populating shared attribute cache for input attribute";
+                DatasetDB::getDatasetAttributesName(DataType::Input, attribute_names);
+                DatasetDB::getDatasetAttributesName(DataType::Bidirectional, attribute_names);
+                initAttributeOnSharedAttributeCache(DOMAIN_INPUT, attribute_names);
+                
+                ACULAPP_ << "Populating shared attribute cache for output attribute";
+                attribute_names.clear();
+                DatasetDB::getDatasetAttributesName(DataType::Output, attribute_names);
+                DatasetDB::getDatasetAttributesName(DataType::Bidirectional, attribute_names);
+                initAttributeOnSharedAttributeCache(DOMAIN_OUTPUT, attribute_names);
+                break;
             }
-            case DataType::TYPE_INT64: {
-              int64_t i64v = dataset_attribute_values->getInt64Value(attr_name);
-              CHECK_FOR_RANGE_VALUE(int64_t, i64v, attr_name)
-              attribute_cache_value->setValue(&i64v, sizeof(int64_t));
-              break;
+            
+            CHAOS_CHECK_LIST_DONE(check_list_sub_service, "_init", INIT_RPC_PHASE_COMPLETE_OUTPUT_ATTRIBUTE) {
+                ACULAPP_ << "Complete shared attribute cache for output attribute";
+                completeOutputAttribute();
+                break;
             }
-            case DataType::TYPE_DOUBLE: {
-              double dv = dataset_attribute_values->getDoubleValue(attr_name);
-              CHECK_FOR_RANGE_VALUE(double, dv, attr_name)
-              attribute_cache_value->setValue(&dv, sizeof(double));
-              break;
+            CHAOS_CHECK_LIST_DONE(check_list_sub_service, "_init", INIT_RPC_PHASE_COMPLETE_INPUT_ATTRIBUTE) {
+                ACULAPP_ << "Complete shared attribute cache for input attribute";
+                completeInputAttribute();
+                break;
             }
-
-            case DataType::TYPE_CLUSTER: {
-              ChaosUniquePtr<CDataWrapper> str = dataset_attribute_values->getCSDataValue(attr_name);
-              try {
-                if (str.get()) {
-                  attribute_cache_value->setValue(*(str.get()));
+            
+            CHAOS_CHECK_LIST_DONE(check_list_sub_service, "_init", INIT_RPC_PHASE_INIT_SYSTEM_CACHE) {
+                ACULAPP_ << "Populating shared attribute cache for system attribute";
+                initSystemAttributeOnSharedAttributeCache();
+                break;
+            }
+            CHAOS_CHECK_LIST_DONE(check_list_sub_service, "_init", INIT_RPC_PHASE_CALL_UNIT_DEFINE_ATTRIBUTE) {
+                std::string cu_load_param=getCUParam();
+                
+                if(isCUParamInJson()){
+                    getAttributeCache()->addCustomAttribute(chaos::ControlUnitNodeDefinitionKey::CONTROL_UNIT_LOAD_PARAM, cu_load_param.size(),
+                                                            chaos::DataType::TYPE_CLUSTER);
+                } else {
+                    getAttributeCache()->addCustomAttribute(chaos::ControlUnitNodeDefinitionKey::CONTROL_UNIT_LOAD_PARAM, cu_load_param.size(),
+                                                            chaos::DataType::TYPE_STRING);
                 }
-              } catch (...) {
-                throw MetadataLoggingCException(getCUID(), -1, boost::str(boost::format("Invalid Json format ")).c_str(), __PRETTY_FUNCTION__);
-              }
-              break;
+                getAttributeCache()->setCustomAttributeValue(chaos::ControlUnitNodeDefinitionKey::CONTROL_UNIT_LOAD_PARAM, (void *)cu_load_param.c_str(),
+                                                             cu_load_param.size());
+                
+                //define the implementations custom variable
+                unitDefineCustomAttribute();
+                break;
             }
-            case DataType::TYPE_STRING: {
-              std::string str = dataset_attribute_values->getStringValue(attr_name);
-              CHECK_FOR_STRING_RANGE_VALUE(str, attr_name)
-              attribute_cache_value->setValue(str.c_str(), (uint32_t)str.size());
-              break;
+            CHAOS_CHECK_LIST_DONE(check_list_sub_service, "_init", INIT_RPC_PHASE_CREATE_FAST_ACCESS_CASCHE_VECTOR) {
+                //create fast vector access for cached value
+                fillCachedValueVector(attribute_value_shared_cache->getSharedDomain(DOMAIN_OUTPUT),
+                                      cache_output_attribute_vector);
+                
+                fillCachedValueVector(attribute_value_shared_cache->getSharedDomain(DOMAIN_INPUT),
+                                      cache_input_attribute_vector);
+                
+                fillCachedValueVector(attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM),
+                                      cache_system_attribute_vector);
+                
+                fillCachedValueVector(attribute_value_shared_cache->getSharedDomain(DOMAIN_CUSTOM),
+                                      cache_custom_attribute_vector);
+                break;
+            }
+            CHAOS_CHECK_LIST_DONE(check_list_sub_service, "_init", INIT_RPC_PHASE_CALL_UNIT_INIT) {
+                //initialize implementations
+                unitInit();
+                break;
+            }
+            CHAOS_CHECK_LIST_DONE(check_list_sub_service, "_init", INIT_RPC_PHASE_UPDATE_CONFIGURATION) {
+                //call update param function
+                updateConfiguration(MOVE(init_configuration->clone()));
+                
+                //check if we need to do a restore on first start
+                PropertyGroupShrdPtr cug = PropertyCollector::getGroup(chaos::ControlUnitPropertyKey::P_GROUP_NAME);
+                if (cug.get()) {
+                    if (cug->hasProperty(chaos::ControlUnitPropertyKey::INIT_RESTORE_APPLY) &&
+                        cug->getProperty(chaos::ControlUnitPropertyKey::INIT_RESTORE_APPLY).getPropertyValue().isValid() &&
+                        cug->getProperty(chaos::ControlUnitPropertyKey::INIT_RESTORE_APPLY).getPropertyValue().asBool()) {
+                        //we need to add to stsart phase the restore one
+                        check_list_sub_service.getSharedCheckList("_start")->addElement(START_RPC_PHASE_RESTORE_ON_FIRST_START);
+                    }
+                }
+                
+                // try to call handler as setdataset attribute
+                if(init_configuration->hasKey(ControlUnitNodeDefinitionKey::CONTROL_UNIT_DATASET_DESCRIPTION)){
+                    ChaosUniquePtr<chaos::common::data::CDataWrapper> dataset_object(init_configuration->getCSDataValue(ControlUnitNodeDefinitionKey::CONTROL_UNIT_DATASET_DESCRIPTION));
+                    if(dataset_object->hasKey(ControlUnitNodeDefinitionKey::CONTROL_UNIT_DATASET_DESCRIPTION)) {
+                        CDWUniquePtr cdw_unique_ptr(new CDataWrapper());
+                        cdw_unique_ptr->addStringValue(NodeDefinitionKey::NODE_UNIQUE_ID, getCUID());
+                        //get the entity for device
+                        CMultiTypeDataArrayWrapperSPtr elementsDescriptions = dataset_object->getVectorValue(ControlUnitNodeDefinitionKey::CONTROL_UNIT_DATASET_DESCRIPTION);
+                        
+                        for (int idx = 0; idx < elementsDescriptions->size(); idx++) {
+                            
+                            //next element in dataset
+                            CDWUniquePtr elementDescription=elementsDescriptions->getCDataWrapperElementAtIndex(idx);
+                            //attribute name
+                            
+                            if(!elementDescription->hasKey(ControlUnitNodeDefinitionKey::CONTROL_UNIT_DATASET_ATTRIBUTE_NAME) ||
+                               !elementDescription->hasKey(ControlUnitNodeDefinitionKey::CONTROL_UNIT_DATASET_ATTRIBUTE_NAME) ||
+                               !elementDescription->hasKey(ControlUnitNodeDefinitionKey::CONTROL_UNIT_DATASET_ATTRIBUTE_NAME) ) {
+                                continue;
+                            }
+                            string attrName = elementDescription->getStringValue(ControlUnitNodeDefinitionKey::CONTROL_UNIT_DATASET_ATTRIBUTE_NAME);
+                            int32_t attrType = elementDescription->getInt32Value(ControlUnitNodeDefinitionKey::CONTROL_UNIT_DATASET_ATTRIBUTE_TYPE);
+                            string attrValue = elementDescription->getStringValue(ControlUnitNodeDefinitionKey::CONTROL_UNIT_DATASET_DEFAULT_VALUE);
+                            switch(attrType) {
+                                case DataType::TYPE_BOOLEAN:
+                                    cdw_unique_ptr->addBoolValue(attrName, CDataVariant(attrValue).asBool());
+                                    break;
+                                case DataType::TYPE_INT32:
+                                    cdw_unique_ptr->addInt32Value(attrName, CDataVariant(attrValue).asInt32());
+                                    break;
+                                case DataType::TYPE_INT64:
+                                    cdw_unique_ptr->addInt64Value(attrName, CDataVariant(attrValue).asInt64());
+                                    break;
+                                case DataType::TYPE_DOUBLE:
+                                    cdw_unique_ptr->addDoubleValue(attrName, CDataVariant(attrValue).asDouble());
+                                    break;
+                                case DataType::TYPE_STRING:
+                                    cdw_unique_ptr->addStringValue(attrName, attrValue);
+                                    break;
+                                case DataType::TYPE_CLUSTER:
+                                    cdw_unique_ptr->addStringValue(attrName, attrValue);
+                                    break;
+                                case DataType::TYPE_BYTEARRAY:
+                                    CDataVariant v(attrValue);
+                                    cdw_unique_ptr->addBinaryValue(attrName,
+                                                                   v.asCDataBuffer()->getBuffer(),
+                                                                   (uint32_t)v.asCDataBuffer()->getBufferSize());
+                                    break;
+                            }
+                        }
+                        CDWUniquePtr res = setDatasetAttribute(MOVE(cdw_unique_ptr));
+                    }
+                }
+                break;
             }
-            case DataType::TYPE_BYTEARRAY: {
-              uint32_t    bin_size = 0;
-              const char* binv     = dataset_attribute_values->getBinaryValue(attr_name, bin_size);
-              attribute_cache_value->setValue(binv, bin_size);
-              break;
+            CHAOS_CHECK_LIST_DONE(check_list_sub_service, "_init", INIT_RPC_PHASE_PUSH_DATASET) {
+                //init on shared cache the all the dataaset with the default value
+                //set first timestamp for simulate the run step
+                int err;
+                *timestamp_acq_cached_value->getValuePtr<uint64_t>() = TimingUtil::getTimeStamp();
+                attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM).markAllAsChanged();
+                /*
+                 *if ((err = pushSystemDataset()) != 0) {
+                 ACULWRN_ << "cannot initialize system dataset, retrying";
+                 sleep(1);
+                 if ((err = pushSystemDataset()) != 0) {
+                 throw CException(err, "cannot initialize system dataset", __PRETTY_FUNCTION__);
+                 }
+                 }
+                 */
+                if ((err = pushSystemDataset()) != 0) {
+                    throw CException(err, "cannot initialize system dataset (check live services)", __PRETTY_FUNCTION__);
+                }
+                /*if ((err = pushCUAlarmDataset()) != 0) {
+                 ACULWRN_ << "cannot initialize CUAlarm dataset, retrying";
+                 sleep(1);
+                 if ((err = pushCUAlarmDataset()) != 0) {
+                 throw CException(err, "cannot initialize CU alarm dataset", __PRETTY_FUNCTION__);
+                 }
+                 }*/
+                if ((err = pushCUAlarmDataset()) != 0) {
+                    throw CException(err, "cannot initialize CU alarm dataset (check live services)", __PRETTY_FUNCTION__);
+                }
+                /*if ((err = pushDevAlarmDataset()) != 0) {
+                 ACULWRN_ << "cannot initialize DEVAlarm dataset, retrying";
+                 if ((err = pushDevAlarmDataset()) != 0) {
+                 throw CException(err, "cannot initialize DEV alarm dataset", __PRETTY_FUNCTION__);
+                 }
+                 }*/
+                if ((err = pushDevAlarmDataset()) != 0) {
+                    throw CException(err, "cannot initialize DEV alarm dataset (check live services)", __PRETTY_FUNCTION__);
+                }
+                attribute_value_shared_cache->getSharedDomain(DOMAIN_OUTPUT).markAllAsChanged();
+                // if the CU can't push initial dataset is a real problem, we must detect immediately
+                /* if ((err = pushOutputDataset()) != 0) {
+                 ACULWRN_ << "cannot initialize output dataset, err:"<<err<<" retrying..";
+                 sleep(1);
+                 if ((err = pushOutputDataset()) != 0) {
+                 throw CException(err, "cannot initialize output dataset", __PRETTY_FUNCTION__);
+                 }
+                 }*/
+                if ((err = pushOutputDataset()) != 0) {
+                    throw CException(err, "cannot initialize output dataset (check live services)", __PRETTY_FUNCTION__);
+                }
+                attribute_value_shared_cache->getSharedDomain(DOMAIN_INPUT).markAllAsChanged();
+                
+                /*
+                 if ((err = pushInputDataset()) != 0) {
+                 ACULWRN_ << "cannot initialize input dataset, retrying";
+                 sleep(1);
+                 if ((err = pushInputDataset()) != 0) {
+                 throw CException(err, "cannot initialize input dataset", __PRETTY_FUNCTION__);
+                 }
+                 }*/
+                if ((err = pushInputDataset()) != 0) {
+                    throw CException(err, "cannot initialize input dataset (check live services)", __PRETTY_FUNCTION__);
+                }
+                
+                attribute_value_shared_cache->getSharedDomain(DOMAIN_CUSTOM).markAllAsChanged();
+                
+                if ((err = pushCustomDataset()) != 0) {
+                    throw CException(err, "cannot initialize custom dataset (check live services)", __PRETTY_FUNCTION__);
+                }
+                break;
             }
-            default:
-              break;
-          }
         }
-      }
-      //push the input attribute dataset
-      pushInputDataset();
+        CHAOS_CHECK_LIST_END_SCAN_TO_DO(check_list_sub_service, "_init")
     }
-
-    //inform the subclass for the change
-    unitInputAttributeChangedHandler();
-  } catch (CException& ex) {
-    //inform the subclass for the change
-    unitInputAttributeChangedHandler();
-    throw;
-  }
-  return CDWUniquePtr();
-}
-
-/*
- Update the configuration for all descendant tree in the Control Unit class structure
- */
-CDWUniquePtr AbstractControlUnit::updateConfiguration(CDWUniquePtr update_pack) {
-  //check to see if the device can ben initialized
-  if (SWEService::getServiceState() != chaos::CUStateKey::INIT &&
-      SWEService::getServiceState() != chaos::CUStateKey::START) {
-    ACULAPP_ << "device:" << DatasetDB::getDeviceID() << " not initialized";
-    throw MetadataLoggingCException(getCUID(), -3, "Device Not Initilized", __PRETTY_FUNCTION__);
-  }
-
-  PropertyGroupVectorSDWrapper pg_sdw;
-  pg_sdw.serialization_key = "property";
-  pg_sdw.deserialize(update_pack.get());
-
-  //update the property
-  PropertyCollector::applyValue(pg_sdw());
-  key_data_storage->updateConfiguration(update_pack.get());
-  //mark all cache as changed
-  attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM).markAllAsChanged();
-
-  pushSystemDataset();
-  return CDWUniquePtr();
-}
-
-bool AbstractControlUnit::propertyChangeHandler(const std::string&  group_name,
-                                                const std::string&  property_name,
-                                                const CDataVariant& property_value) {
-  ACULDBG_ << CHAOS_FORMAT("Update property request for %1%[%2%] with value %3%", % property_name % group_name % property_value.asString());
-  return true;
-}
-
-void AbstractControlUnit::propertyUpdatedHandler(const std::string&  group_name,
-                                                 const std::string&  property_name,
-                                                 const CDataVariant& old_value,
-                                                 const CDataVariant& new_value) {
-  if (group_name.compare("property_abstract_control_unit") == 0) {
-    //update property on driver
-    key_data_storage->updateConfiguration(property_name, new_value);
-    //reflect modification on dataset
-    if (property_name.compare(ControlUnitDatapackSystemKey::BYPASS_STATE) == 0) {
-      _setBypassState(new_value.asBool());
-    } else if (property_name.compare(DataServiceNodeDefinitionKey::DS_STORAGE_TYPE) == 0) {
-      *attribute_value_shared_cache->getAttributeValue(DOMAIN_SYSTEM, DataServiceNodeDefinitionKey::DS_STORAGE_TYPE)->getValuePtr<int32_t>() = new_value.asInt32();
-    } else if (property_name.compare(DataServiceNodeDefinitionKey::DS_STORAGE_LIVE_TIME) == 0) {
-      *attribute_value_shared_cache->getAttributeValue(DOMAIN_SYSTEM, DataServiceNodeDefinitionKey::DS_STORAGE_LIVE_TIME)->getValuePtr<uint64_t>() = new_value.asUInt64();
-    } else if (property_name.compare(DataServiceNodeDefinitionKey::DS_STORAGE_HISTORY_TIME) == 0) {
-      *attribute_value_shared_cache->getAttributeValue(DOMAIN_SYSTEM, DataServiceNodeDefinitionKey::DS_STORAGE_HISTORY_TIME)->getValuePtr<uint64_t>() = new_value.asUInt64();
-    }
-  }
-}
-
-//! return the accessor by an index
-/*
- The index parameter correspond to the order that the driver infromation are
- added by the unit implementation into the function AbstractControlUnit::unitDefineDriver.
- */
-DriverAccessor* AbstractControlUnit::getAccessoInstanceByIndex(int idx) {
-  if (idx >= accessor_instances.size()) return NULL;
-  return accessor_instances[idx];
-}
-
-int AbstractControlUnit::pushOutputDataset() {
-  int                                   err                    = 0;
-  AttributeCache&                       output_attribute_cache = attribute_value_shared_cache->getSharedDomain(DOMAIN_OUTPUT);
-  ChaosSharedPtr<SharedCacheLockDomain> r_lock                 = attribute_value_shared_cache->getLockOnDomain(DOMAIN_OUTPUT, false);
-  r_lock->lock();
-
-  //check if something as changed
-  if (!output_attribute_cache.hasChanged()) {return err;}
-
-  CDWShrdPtr output_attribute_dataset = key_data_storage->getNewDataPackForDomain(KeyDataStorageDomainOutput);
-  if (!output_attribute_dataset.get()) {
-    ACULERR_ << " Cannot allocate packet.. err:"<<err;
-    return err;
-  }
-  output_attribute_dataset->addInt64Value(ControlUnitDatapackCommonKey::RUN_ID, run_id);
-  output_attribute_dataset->addInt64Value(DataPackCommonKey::DPCK_TIMESTAMP, *timestamp_acq_cached_value->getValuePtr<uint64_t>());
-  output_attribute_dataset->addInt64Value(DataPackCommonKey::DPCK_HIGH_RESOLUTION_TIMESTAMP, *timestamp_hw_acq_cached_value->getValuePtr<uint64_t>());
-
-  //add all other output channel
-  for (int idx = 0;
-       idx < ((int)cache_output_attribute_vector.size()) - 1;  //the device id and timestamp in added out of this list
-       idx++) {
-    //
-    AttributeValue* value_set = cache_output_attribute_vector[idx];
-    assert(value_set);
-
-    switch (value_set->type) {
-      case DataType::TYPE_BOOLEAN:
-        output_attribute_dataset->addBoolValue(value_set->name, *value_set->getValuePtr<bool>());
-        break;
-      case DataType::TYPE_INT32:
-        output_attribute_dataset->addInt32Value(value_set->name, *value_set->getValuePtr<int32_t>());
-        break;
-      case DataType::TYPE_INT64:
-        output_attribute_dataset->addInt64Value(value_set->name, *value_set->getValuePtr<int64_t>());
-        break;
-      case DataType::TYPE_DOUBLE:
-        output_attribute_dataset->addDoubleValue(value_set->name, *value_set->getValuePtr<double>());
-        break;
-      case DataType::TYPE_CLUSTER: {
+    void AbstractControlUnit::doInitSMCheckList() {
+        //rpc initialize service
+        CHAOS_CHECK_LIST_START_SCAN_TO_DO(check_list_sub_service, "init") {
+            CHAOS_CHECK_LIST_DONE(check_list_sub_service, "init", INIT_SM_PHASE_INIT_DB) {
+                //cast to the CDatawrapper instance
+                ACULAPP_ << "Initialize CU Database for device:" << DatasetDB::getDeviceID();
+                run_id = CDW_GET_INT64_WITH_DEFAULT(init_configuration, ControlUnitNodeDefinitionKey::CONTROL_UNIT_RUN_ID, 0);
+                DatasetDB::addAttributeToDataSetFromDataWrapper(*init_configuration);
+                break;
+            }
+            CHAOS_CHECK_LIST_DONE(check_list_sub_service, "init", INIT_SM_PHASE_CREATE_DATA_STORAGE) {
+                //call init sequence
+                //call update param function
+                //initialize key data storage for device id
+                ACULAPP_ << "Create KeyDataStorage device:" << DatasetDB::getDeviceID();
+                key_data_storage.reset(DataManager::getInstance()->getKeyDataStorageNewInstanceForKey(DatasetDB::getDeviceID()));
+                
+                ACULAPP_ << "Call KeyDataStorage init implementation for deviceID:" << DatasetDB::getDeviceID();
+                key_data_storage->init(init_configuration.get());
+                break;
+            }
+        }
+        CHAOS_CHECK_LIST_END_SCAN_TO_DO(check_list_sub_service, "init")
+    }
+    
+    void AbstractControlUnit::doStartRpCheckList() {
+        CHAOS_CHECK_LIST_START_SCAN_TO_DO(check_list_sub_service, "_start") {
+            CHAOS_CHECK_LIST_DONE(check_list_sub_service, "_start", START_RPC_PHASE_IMPLEMENTATION) {
+                start();
+                break;
+            }
+            CHAOS_CHECK_LIST_DONE(check_list_sub_service, "_start", START_RPC_PHASE_UNIT) {
+                unitStart();
+                break;
+            }
+            CHAOS_CHECK_LIST_DONE(check_list_sub_service, "_start", START_RPC_PHASE_RESTORE_ON_FIRST_START) {
+                try {
+                    checkForRestoreOnInit();
+                    check_list_sub_service.getSharedCheckList("_start")->removeElement(START_RPC_PHASE_RESTORE_ON_FIRST_START);
+                } catch (CException& ex) {
+                    check_list_sub_service.getSharedCheckList("_start")->removeElement(START_RPC_PHASE_RESTORE_ON_FIRST_START);
+                    throw;
+                }
+                break;
+            }
+        }
+        CHAOS_CHECK_LIST_END_SCAN_TO_DO(check_list_sub_service, "_start")
+    }
+    
+    void AbstractControlUnit::doStartSMCheckList() {
+        CHAOS_CHECK_LIST_START_SCAN_TO_DO(check_list_sub_service, "start") {
+            CHAOS_CHECK_LIST_DONE(check_list_sub_service, "start", START_SM_PHASE_STAT_TIMER) {
+                //register timer for push statistic
+                chaos::common::async_central::AsyncCentralManager::getInstance()->addTimer(this, 0, chaos::common::constants::CUTimersTimeoutinMSec);
+                //get timestamp for first pushes metric acquisition
+                last_push_rate_grap_ts = TimingUtil::getTimeStamp();
+            }
+        }
+        CHAOS_CHECK_LIST_END_SCAN_TO_DO(check_list_sub_service, "start")
+    }
+    
+    void AbstractControlUnit::redoInitRpCheckList(bool throw_exception) {
+        //rpc initialize service
+        CHAOS_CHECK_LIST_START_SCAN_DONE(check_list_sub_service, "_init") {
+            CHAOS_CHECK_LIST_REDO(check_list_sub_service, "_init", INIT_RPC_PHASE_CALL_INIT_STATE) {
+                //saftely deinititalize the abstract control unit
+                CHEK_IF_NEED_TO_THROW(throw_exception, deinit();)
+                break;
+            }
+            CHAOS_CHECK_LIST_REDO(check_list_sub_service, "_init", INIT_RPC_PHASE_INIT_SHARED_CACHE) {
+                ACULAPP_ << "Deallocate the user cache wrapper for:" + DatasetDB::getDeviceID();
+                if (attribute_shared_cache_wrapper) {
+                    delete (attribute_shared_cache_wrapper);
+                    attribute_shared_cache_wrapper = NULL;
+                }
+                break;
+            }
+            CHAOS_CHECK_LIST_REDO(check_list_sub_service, "_init", INIT_RPC_PHASE_COMPLETE_OUTPUT_ATTRIBUTE) {
+                break;
+            }
+            CHAOS_CHECK_LIST_REDO(check_list_sub_service, "_init", INIT_RPC_PHASE_COMPLETE_INPUT_ATTRIBUTE) {
+                break;
+            }
+            CHAOS_CHECK_LIST_REDO(check_list_sub_service, "_init", INIT_RPC_PHASE_INIT_SYSTEM_CACHE) {
+                break;
+            }
+            CHAOS_CHECK_LIST_REDO(check_list_sub_service, "_init", INIT_RPC_PHASE_CALL_UNIT_DEFINE_ATTRIBUTE) {
+                CHEK_IF_NEED_TO_THROW(throw_exception, unitDefineCustomAttribute();)
+                break;
+            }
+            CHAOS_CHECK_LIST_REDO(check_list_sub_service, "_init", INIT_RPC_PHASE_CREATE_FAST_ACCESS_CASCHE_VECTOR) {
+                //clear all cache sub_structure
+                CHEK_IF_NEED_TO_THROW(throw_exception,
+                                      cache_output_attribute_vector.clear();
+                                      cache_input_attribute_vector.clear();
+                                      cache_custom_attribute_vector.clear();
+                                      cache_system_attribute_vector.clear();)
+                break;
+            }
+            CHAOS_CHECK_LIST_REDO(check_list_sub_service, "_init", INIT_RPC_PHASE_CALL_UNIT_INIT) {
+                ACULDBG_ << "Deinit custom deinitialization for device:" << DatasetDB::getDeviceID();
+                CHEK_IF_NEED_TO_THROW(throw_exception, unitDeinit();)
+                break;
+            }
+            CHAOS_CHECK_LIST_REDO(check_list_sub_service, "_init", INIT_RPC_PHASE_UPDATE_CONFIGURATION) {
+                break;
+            }
+            CHAOS_CHECK_LIST_REDO(check_list_sub_service, "_init", INIT_RPC_PHASE_PUSH_DATASET) {
+                break;
+            }
+        }
+        CHAOS_CHECK_LIST_END_SCAN_DONE(check_list_sub_service, "_init")
+    }
+    
+    void AbstractControlUnit::redoInitSMCheckList(bool throw_exception) {
+        CHAOS_CHECK_LIST_START_SCAN_DONE(check_list_sub_service, "init") {
+            CHAOS_CHECK_LIST_REDO(check_list_sub_service, "init", INIT_SM_PHASE_INIT_DB) {
+                break;
+            }
+            CHAOS_CHECK_LIST_REDO(check_list_sub_service, "init", INIT_SM_PHASE_CREATE_DATA_STORAGE) {
+                //remove key data storage
+                CHEK_IF_NEED_TO_THROW(throw_exception,
+                                      if (key_data_storage.get()) {
+                    ACULDBG_ << "Delete data storage driver for device:" << DatasetDB::getDeviceID();
+                    key_data_storage->deinit();
+                    key_data_storage.reset();
+                })
+                break;
+            }
+        }
+        CHAOS_CHECK_LIST_END_SCAN_DONE(check_list_sub_service, "init")
+    }
+    
+    void AbstractControlUnit::redoStartRpCheckList(bool throw_exception) {
+        CHAOS_CHECK_LIST_START_SCAN_DONE(check_list_sub_service, "_start") {
+            CHAOS_CHECK_LIST_REDO(check_list_sub_service, "_start", START_RPC_PHASE_IMPLEMENTATION) {
+                CHEK_IF_NEED_TO_THROW(throw_exception, stop();)
+                break;
+            }
+            //unit sto need to go after the abstract cu has been stopped
+            CHAOS_CHECK_LIST_REDO(check_list_sub_service, "_start", START_RPC_PHASE_UNIT) {
+                CHEK_IF_NEED_TO_THROW(throw_exception, unitStop();)
+            }
+        }
+        CHAOS_CHECK_LIST_END_SCAN_DONE(check_list_sub_service, "_start")
+    }
+    
+    void AbstractControlUnit::redoStartSMCheckList(bool throw_exception) {
+        CHAOS_CHECK_LIST_START_SCAN_DONE(check_list_sub_service, "start") {
+            CHAOS_CHECK_LIST_REDO(check_list_sub_service, "start", START_SM_PHASE_STAT_TIMER) {
+                //remove timer for push statistic
+                CHEK_IF_NEED_TO_THROW(throw_exception, chaos::common::async_central::AsyncCentralManager::getInstance()->removeTimer(this);)
+            }
+        }
+        CHAOS_CHECK_LIST_END_SCAN_DONE(check_list_sub_service, "start")
+    }
+    
+    //----------------------------------------- protected initi/deinit method ------------------------------------------------
+#pragma mark RPC State Machine method
+    CDWUniquePtr AbstractControlUnit::_init(CDWUniquePtr init_configuration) {
+        if (getServiceState() == CUStateKey::INIT) {
+            return CDWUniquePtr();
+        }
+        
         try {
-          output_attribute_dataset->addCSDataValue(value_set->name, *value_set->getValuePtr<CDataWrapper>());
-        } catch (...) {
-          throw MetadataLoggingCException(getCUID(), -101, boost::str(boost::format("Invalid Json format for attribute '%1%' :'%2%") % value_set->name % value_set->getValuePtr<const char>()).c_str(), __PRETTY_FUNCTION__);
-        }
-        break;
-      }
-      case DataType::TYPE_STRING:
-        //DEBUG_CODE(ACULAPP_ << value_set->name<<"-"<<value_set->getValuePtr<const char>();)
-        output_attribute_dataset->addStringValue(value_set->name, value_set->getValuePtr<const char>());
-        break;
-      case DataType::TYPE_BYTEARRAY:
-        if (value_set->size) {
-          if (value_set->sub_type.size() == 1) {
-            output_attribute_dataset->addBinaryValue(value_set->name, value_set->sub_type[0], value_set->getValuePtr<char>(), value_set->size);
-          } else {
-            output_attribute_dataset->addBinaryValue(value_set->name, value_set->getValuePtr<char>(), value_set->size);
-          }
-        }
-        break;
-      default:
-        break;
-    }
-  }
-  //manage the burst information
-  manageBurstQueue();
-  //now we nede to push the outputdataset
-  push_dataset_size+=output_attribute_dataset->getBSONRawSize();
-  err = key_data_storage->pushDataSet(data_manager::KeyDataStorageDomainOutput, MOVE(output_attribute_dataset));
-
-  //update counter
-  push_dataset_counter++;
-
-  //reset chagned attribute into output dataset
-  if(!err){output_attribute_cache.resetChangedIndex();}
-  return err;
-}
-
-//push system dataset
-int AbstractControlUnit::pushInputDataset() {
-  int             err                   = 0;
-  AttributeCache& input_attribute_cache = attribute_value_shared_cache->getSharedDomain(DOMAIN_INPUT);
-  if (!input_attribute_cache.hasChanged()) return err;
-  //get the cdatawrapper for the pack
-  int64_t    cur_us                  = TimingUtil::getTimeStampInMicroseconds();
-  CDWShrdPtr input_attribute_dataset = key_data_storage->getNewDataPackForDomain(KeyDataStorageDomainInput);
-  if (input_attribute_dataset.get()) {
-    input_attribute_dataset->addInt64Value(ControlUnitDatapackCommonKey::RUN_ID, run_id);
-    //input dataset timestamp is added only when pushed on cache
-    input_attribute_dataset->addInt64Value(DataPackCommonKey::DPCK_TIMESTAMP, cur_us / 1000);
-    input_attribute_dataset->addInt64Value(DataPackCommonKey::DPCK_HIGH_RESOLUTION_TIMESTAMP, cur_us);
-    //fill the dataset
-    fillCDatawrapperWithCachedValue(cache_input_attribute_vector, *input_attribute_dataset);
-
-    //push out the system dataset
-    err = key_data_storage->pushDataSet(data_manager::KeyDataStorageDomainInput, MOVE(input_attribute_dataset));
-    if(!err){input_attribute_cache.resetChangedIndex();}
-  } else {
-    ACULERR_ << " Cannot allocate packet.. err:"<<err;
-  }
-  return err;
-}
-
-//push system dataset
-int AbstractControlUnit::pushCustomDataset() {
-  int             err                    = 0;
-  AttributeCache& custom_attribute_cache = attribute_value_shared_cache->getSharedDomain(DOMAIN_CUSTOM);
-  if (!custom_attribute_cache.hasChanged()) return err;
-  //get the cdatawrapper for the pack
-  int64_t    cur_us                   = TimingUtil::getTimeStampInMicroseconds();
-  if(key_data_storage.get()){
-    CDWShrdPtr custom_attribute_dataset = key_data_storage->getNewDataPackForDomain(KeyDataStorageDomainCustom);
-  if (custom_attribute_dataset.get()) {
-    custom_attribute_dataset->addInt64Value(ControlUnitDatapackCommonKey::RUN_ID, run_id);
-    //input dataset timestamp is added only when pushed on cache
-    custom_attribute_dataset->addInt64Value(DataPackCommonKey::DPCK_TIMESTAMP, cur_us / 1000);
-    custom_attribute_dataset->addInt64Value(DataPackCommonKey::DPCK_HIGH_RESOLUTION_TIMESTAMP, cur_us);
-
-    //fill the dataset
-    fillCDatawrapperWithCachedValue(cache_custom_attribute_vector, *custom_attribute_dataset);
-
-    //push out the system dataset
-    err = key_data_storage->pushDataSet(data_manager::KeyDataStorageDomainCustom, MOVE(custom_attribute_dataset));
-    if(!err){custom_attribute_cache.resetChangedIndex();}
-  } else {
-        ACULERR_ << " Cannot allocate packet.. err:"<<err;
-  }
-  }
-  return err;
-}
-
-int AbstractControlUnit::pushSystemDataset() {
-  int err = 0;
-  AttributeCache& system_attribute_cache = attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM);
-  if (!system_attribute_cache.hasChanged()) return err;
-  //get the cdatawrapper for the pack
-  int64_t    cur_us                   = TimingUtil::getTimeStampInMicroseconds();
-  CDWShrdPtr system_attribute_dataset = key_data_storage->getNewDataPackForDomain(KeyDataStorageDomainSystem);
-  if (system_attribute_dataset) {
-    system_attribute_dataset->addInt64Value(ControlUnitDatapackCommonKey::RUN_ID, run_id);
-    //input dataset timestamp is added only when pushed on cache
-    system_attribute_dataset->addInt64Value(DataPackCommonKey::DPCK_TIMESTAMP, cur_us / 1000);
-    system_attribute_dataset->addInt64Value(DataPackCommonKey::DPCK_HIGH_RESOLUTION_TIMESTAMP, cur_us);
-    //fill the dataset
-    fillCDatawrapperWithCachedValue(cache_system_attribute_vector, *system_attribute_dataset);
-    //ACULDBG_ << system_attribute_dataset->getJSONString();
-    //push out the system dataset
-    err = key_data_storage->pushDataSet(data_manager::KeyDataStorageDomainSystem, MOVE(system_attribute_dataset));
-    if(!err){system_attribute_cache.resetChangedIndex();}
-  }
-  return err;
-}
-
-CDWShrdPtr AbstractControlUnit::writeCatalogOnCDataWrapper(AlarmCatalog& catalog,
-                                                           int32_t       dataset_type) {
-  CDWShrdPtr attribute_dataset = key_data_storage->getNewDataPackForDomain((KeyDataStorageDomain)dataset_type);
-  if (attribute_dataset) {
-    //fill datapack with
-    //! the dataaset can be pushed also in other moment
-    attribute_dataset->addInt64Value(DataPackCommonKey::DPCK_TIMESTAMP, TimingUtil::getTimeStamp());
-    attribute_dataset->addInt64Value(ControlUnitDatapackCommonKey::RUN_ID, run_id);
-    //scan all alarm ad create the datapack
-    size_t alarm_size = catalog.size();
-    for (unsigned int idx = 0;
-         idx < alarm_size;
-         idx++) {
-      AlarmDescription* alarm = catalog.getAlarmByOrderedID(idx);
-      attribute_dataset->addInt32Value(alarm->getAlarmName(),
-                                       (uint32_t)alarm->getCurrentSeverityCode());
-    }
-  }
-  return attribute_dataset;
-}
-
-int AbstractControlUnit::pushDevAlarmDataset() {
-  GET_CAT_OR_EXIT(StateVariableTypeAlarmDEV, 0);
-  int err = 0;
-
-  CDWShrdPtr attribute_dataset = writeCatalogOnCDataWrapper(catalog,
-                                                            DataPackCommonKey::DPCK_DATASET_TYPE_DEV_ALARM);
-  if (attribute_dataset) {
-    //push out the system dataset
-    err = key_data_storage->pushDataSet(KeyDataStorageDomainDevAlarm, MOVE(attribute_dataset));
-  }
-  return err;
-}
-
-int AbstractControlUnit::pushCUAlarmDataset() {
-  GET_CAT_OR_EXIT(StateVariableTypeAlarmCU, 0);
-  int        err               = 0;
-  CDWShrdPtr attribute_dataset = writeCatalogOnCDataWrapper(catalog,
-                                                            DataPackCommonKey::DPCK_DATASET_TYPE_CU_ALARM);
-  if (attribute_dataset) {
-    //push out the system dataset
-    err = key_data_storage->pushDataSet(KeyDataStorageDomainCUAlarm, MOVE(attribute_dataset));
-  }
-  return err;
-}
-
-void AbstractControlUnit::manageBurstQueue() {
-  if (!current_burst.get()) {
-    DatasetBurstShrdPtr next_burst;
-    LQueueBurstReadLock wl = burst_queue.getReadLockObject();
-    if (!burst_queue().empty()) {
-      next_burst = burst_queue().front();
-      burst_queue().pop();
-    }
-    wl->unlock();
-
-    if (next_burst.get()) {
-      switch (next_burst->type) {
-        case chaos::ControlUnitNodeDefinitionType::DSStorageBurstTypeNPush:
-          current_burst.reset(new PushStorageBurst(next_burst));
-          break;
-        case chaos::ControlUnitNodeDefinitionType::DSStorageBurstTypeMSec:
-          current_burst.reset(new MSecStorageBurst(next_burst));
-          break;
-        default:
-          break;
-      }
-
-      //set the tag for burst
-      ACULDBG_ << "======= Start Burst tag:'" << current_burst->dataset_burst->tag << "' =======";
-      key_data_storage->addTag(current_burst->dataset_burst->tag);
-      key_data_storage->setTimingConfigurationBehaviour(false);
-      key_data_storage->setOverrideStorageType(DataServiceNodeDefinitionType::DSStorageTypeHistory);
-      *attribute_value_shared_cache->getAttributeValue(DOMAIN_SYSTEM, ControlUnitDatapackSystemKey::BURST_STATE)->getValuePtr<bool>() = true;
-      attribute_value_shared_cache->getAttributeValue(DOMAIN_SYSTEM, ControlUnitDatapackSystemKey::BURST_TAG)->setStringValue(current_burst->dataset_burst->tag, true, true);
-      attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM).markAllAsChanged();
-      pushSystemDataset();
-    }
-  } else {
-    if (!current_burst->active(timestamp_acq_cached_value->getValuePtr<int64_t>())) {
-      //remove the tag for the burst
-      ACULDBG_ << "======= End Burst tag:'" << current_burst->dataset_burst->tag << "' =======";
-      key_data_storage->removeTag(current_burst->dataset_burst->tag);
-      key_data_storage->setTimingConfigurationBehaviour(true);
-      key_data_storage->setOverrideStorageType(DataServiceNodeDefinitionType::DSStorageTypeUndefined);
-      *attribute_value_shared_cache->getAttributeValue(DOMAIN_SYSTEM, ControlUnitDatapackSystemKey::BURST_STATE)->getValuePtr<bool>() = false;
-      attribute_value_shared_cache->getAttributeValue(DOMAIN_SYSTEM, ControlUnitDatapackSystemKey::BURST_TAG)->setStringValue("");
-      attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM).markAllAsChanged();
-      //we need to remove it
-      current_burst.reset();
-      pushSystemDataset();
-    } else {
-      ACULDBG_ << "======= Active Burst tag:'" << current_burst->dataset_burst->tag << "' =======";
-    }
-  }
-}
-
-void AbstractControlUnit::fillCDatawrapperWithCachedValue(std::vector<AttributeValue*>& cached_attributes, CDataWrapper& dataset) {
-  for (std::vector<AttributeValue*>::iterator it = cached_attributes.begin();
-       it != cached_attributes.end();
-       it++) {
-    (*it)->writeToCDataWrapper(dataset);
-  }
-}
-
-//!timer for update push metric
-void AbstractControlUnit::timeout() {
-  //update push metric
-  _updatePushRateMetric();
-}
-
-bool AbstractControlUnit::isInputAttributeChangeAuthorizedByHandler(const std::string& attr_name) {
-  return dataset_attribute_manager.getHandlerResult(attr_name);
-}
-
-void AbstractControlUnit::copyInitConfiguraiton(CDataWrapper& copy) {
-  if (init_configuration.get() == NULL) return;
-
-  //copy all key
-  init_configuration->copyAllTo(copy);
-}
-
+            if (getServiceState() == CUStateKey::RECOVERABLE_ERROR) {
+                LOG_AND_TROW_FORMATTED(ACULERR_, -2, "Recoverable error state need to be recovered for %1%", % __PRETTY_FUNCTION__)
+            }
+            
+            //if(getServiceState() != CUStateKey::DEINIT) throw CException(-1, DatasetDB::getDeviceID()+" need to be in deinit", __PRETTY_FUNCTION__);
+            if (!attribute_value_shared_cache) {
+                LOG_AND_TROW_FORMATTED(ACULERR_, -3, "No Shared cache implementation found for %1%[%2%]", % DatasetDB::getDeviceID() % __PRETTY_FUNCTION__);
+            }
+            
+            if (!SWEService::initImplementation(this, "AbstractControlUnit", __PRETTY_FUNCTION__)) {
+                LOG_AND_TROW_FORMATTED(ACULERR_, -1, "Control Unit %1% can't be initilized [state mismatch]!", % DatasetDB::getDeviceID());
+            }
+            
+        } catch (MetadataLoggingCException& ex) {
+            throw;
+        } catch (CException& ex) {
+            throw MetadataLoggingCException(getCUID(),
+                                            ex.errorCode,
+                                            ex.errorMessage,
+                                            ex.errorDomain);
+        }
+        
+        try {
+            //update configuraiton and own it
+            this->init_configuration = MOVE(init_configuration);
+            
+            HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
+                                                            NodeHealtDefinitionKey::NODE_HEALT_STATUS,
+                                                            NodeHealtDefinitionValue::NODE_HEALT_STATUS_INITING,
+                                                            true);
+            doInitRpCheckList();
+            
+            //set healt to init
+            HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
+                                                            NodeHealtDefinitionKey::NODE_HEALT_STATUS,
+                                                            NodeHealtDefinitionValue::NODE_HEALT_STATUS_INIT,
+                                                            true);
+        } catch (MetadataLoggingCException& ex) {
+            SWEService::goInFatalError(this,
+                                       ex,
+                                       "AbstractControlUnit",
+                                       __PRETTY_FUNCTION__);
+            throw;
+        } catch (CException& ex) {
+            MetadataLoggingCException loggable_exception(getCUID(),
+                                                         ex.errorCode,
+                                                         ex.errorMessage,
+                                                         ex.errorDomain);
+            //go in falta error
+            SWEService::goInFatalError(this,
+                                       loggable_exception,
+                                       "AbstractControlUnit",
+                                       __PRETTY_FUNCTION__);
+            throw loggable_exception;
+        }
+        return CDWUniquePtr();
+    }
+    
+    CDWUniquePtr AbstractControlUnit::_start(CDWUniquePtr startParam) {
+        if (getServiceState() == CUStateKey::START) {
+            return CDWUniquePtr();
+        }
+        try {
+            if (getServiceState() == CUStateKey::RECOVERABLE_ERROR) {
+                LOG_AND_TROW_FORMATTED(ACULERR_, -1, "Recoverable error state need to be recovered for %1%", % __PRETTY_FUNCTION__)
+            }
+            //call start method of the startable interface
+            if (!SWEService::startImplementation(this, "AbstractControlUnit", __PRETTY_FUNCTION__)) {
+                LOG_AND_TROW_FORMATTED(ACULERR_, -1, "Control Unit %1% can't be started [state mismatch]!", % DatasetDB::getDeviceID());
+            }
+            
+        } catch (MetadataLoggingCException& ex) {
+            throw;
+        } catch (CException& ex) {
+            throw MetadataLoggingCException(getCUID(),
+                                            ex.errorCode,
+                                            ex.errorMessage,
+                                            ex.errorDomain);
+        }
+        
+        try {
+            HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
+                                                            NodeHealtDefinitionKey::NODE_HEALT_STATUS,
+                                                            NodeHealtDefinitionValue::NODE_HEALT_STATUS_STARTING,
+                                                            true);
+            
+            doStartRpCheckList();
+            
+            //set healt to start
+            HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
+                                                            NodeHealtDefinitionKey::NODE_HEALT_STATUS,
+                                                            NodeHealtDefinitionValue::NODE_HEALT_STATUS_START,
+                                                            true);
+        } catch (MetadataLoggingCException& ex) {
+            SWEService::goInFatalError(this,
+                                       ex,
+                                       "AbstractControlUnit",
+                                       __PRETTY_FUNCTION__);
+            throw;
+        } catch (CException& ex) {
+            MetadataLoggingCException loggable_exception(getCUID(),
+                                                         ex.errorCode,
+                                                         ex.errorMessage,
+                                                         ex.errorDomain);
+            //go in falta error
+            SWEService::goInFatalError(this, loggable_exception, "AbstractControlUnit", __PRETTY_FUNCTION__);
+            throw loggable_exception;
+        }
+        return CDWUniquePtr();
+    }
+    
+    CDWUniquePtr AbstractControlUnit::_stop(CDWUniquePtr stopParam) {
+        if (getServiceState() == CUStateKey::STOP) {
+            return CDWUniquePtr();
+        }
+        try {
+            /*
+             * stop transition is possible with recoverable error
+             *  if(getServiceState() == CUStateKey::RECOVERABLE_ERROR) {
+             LOG_AND_TROW_FORMATTED(ACULERR_, -1, "Recoverable error state need to be recovered for %1%", %__PRETTY_FUNCTION__)
+             }
+             */
+            //first we start the deinitializaiton of the implementation unit
+            if (!SWEService::stopImplementation(this, "AbstractControlUnit", __PRETTY_FUNCTION__)) {
+                LOG_AND_TROW_FORMATTED(ACULERR_, -1, "Control Unit %1% can't be stopped [state mismatch]!", % DatasetDB::getDeviceID());
+            }
+        } catch (MetadataLoggingCException& ex) {
+            SWEService::goInFatalError(this,
+                                       ex,
+                                       "AbstractControlUnit",
+                                       __PRETTY_FUNCTION__);
+            throw;
+        } catch (CException& ex) {
+            throw MetadataLoggingCException(getCUID(),
+                                            ex.errorCode,
+                                            ex.errorMessage,
+                                            ex.errorDomain);
+        }
+        
+        try {
+            //set healt to start
+            HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
+                                                            NodeHealtDefinitionKey::NODE_HEALT_STATUS,
+                                                            NodeHealtDefinitionValue::NODE_HEALT_STATUS_STOPING,
+                                                            true);
+            redoStartRpCheckList();
+            
+            HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
+                                                            NodeHealtDefinitionKey::NODE_HEALT_STATUS,
+                                                            NodeHealtDefinitionValue::NODE_HEALT_STATUS_STOP,
+                                                            true);
+        } catch (MetadataLoggingCException& ex) {
+            SWEService::goInFatalError(this,
+                                       ex,
+                                       "AbstractControlUnit",
+                                       __PRETTY_FUNCTION__);
+            throw;
+        } catch (CException& ex) {
+            MetadataLoggingCException loggable_exception(getCUID(),
+                                                         ex.errorCode,
+                                                         ex.errorMessage,
+                                                         ex.errorDomain);
+            //go in falta error
+            SWEService::goInFatalError(this, loggable_exception, "AbstractControlUnit", __PRETTY_FUNCTION__);
+            throw loggable_exception;
+        }
+        
+        return CDWUniquePtr();
+    }
+    
+    /*go
+     deinit all datastorage
+     */
+    CDWUniquePtr AbstractControlUnit::_deinit(CDWUniquePtr deinitParam) {
+        if (getServiceState() == CUStateKey::DEINIT) {
+            return CDWUniquePtr();
+        }
+        try {
+            /*
+             * deinit transition is possible with recoverable error
+             *  if(getServiceState() == CUStateKey::RECOVERABLE_ERROR) {
+             LOG_AND_TROW_FORMATTED(ACULERR_, -1, "Recoverable error state need to be recovered for %1%", %__PRETTY_FUNCTION__)
+             }
+             */
+            if (!SWEService::deinitImplementation(this, "AbstractControlUnit", __PRETTY_FUNCTION__)) {
+                LOG_AND_TROW_FORMATTED(ACULERR_, -1, "Control Unit %1% can't be deinitilized [state mismatch]!", % DatasetDB::getDeviceID());
+            }
+        } catch (MetadataLoggingCException& ex) {
+            throw;
+        } catch (CException& ex) {
+            throw MetadataLoggingCException(getCUID(),
+                                            ex.errorCode,
+                                            ex.errorMessage,
+                                            ex.errorDomain);
+        }
+        
+        //first we start the deinitializaiton of the implementation unit
+        try {
+            HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
+                                                            NodeHealtDefinitionKey::NODE_HEALT_STATUS,
+                                                            NodeHealtDefinitionValue::NODE_HEALT_STATUS_DEINITING,
+                                                            true);
+            
+            redoInitRpCheckList();
+            
+            //set healt to deinit
+            HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
+                                                            NodeHealtDefinitionKey::NODE_HEALT_STATUS,
+                                                            NodeHealtDefinitionValue::NODE_HEALT_STATUS_DEINIT,
+                                                            true);
+        } catch (MetadataLoggingCException& ex) {
+            SWEService::goInFatalError(this,
+                                       ex,
+                                       "AbstractControlUnit",
+                                       __PRETTY_FUNCTION__);
+            throw;
+        } catch (CException& ex) {
+            MetadataLoggingCException loggable_exception(getCUID(),
+                                                         ex.errorCode,
+                                                         ex.errorMessage,
+                                                         ex.errorDomain);
+            
+            //go in falta error
+            SWEService::goInFatalError(this, loggable_exception, "AbstractControlUnit", __PRETTY_FUNCTION__);
+            throw loggable_exception;
+        }
+        
+        return CDWUniquePtr();
+    }
+    
+    CDWUniquePtr AbstractControlUnit::_recover(CDWUniquePtr gdeinitParam) {
+        if (getServiceState() != CUStateKey::RECOVERABLE_ERROR) throw MetadataLoggingCException(getCUID(), -1, DatasetDB::getDeviceID() + " need to be recoverable errore in the way to be recoverable!", __PRETTY_FUNCTION__);
+        
+        //first we start the deinitializaiton of the implementation unit
+        try {
+            if (SWEService::recoverError(this, "AbstractControlUnit", __PRETTY_FUNCTION__)) {
+            } else {
+            }
+        } catch (MetadataLoggingCException& ex) {
+            SWEService::goInFatalError(this,
+                                       ex,
+                                       "AbstractControlUnit",
+                                       __PRETTY_FUNCTION__);
+            throw;
+        } catch (CException& ex) {
+            MetadataLoggingCException loggable_exception(getCUID(),
+                                                         ex.errorCode,
+                                                         ex.errorMessage,
+                                                         ex.errorDomain);
+            //go in falta error
+            SWEService::goInFatalError(this, loggable_exception, "AbstractControlUnit", __PRETTY_FUNCTION__);
+            throw loggable_exception;
+        }
+        
+        return CDWUniquePtr();
+    }
+    
+    //! fill cache with found dataset at the restore point
+    void AbstractControlUnit::fillRestoreCacheWithDatasetFromTag(chaos::cu::data_manager::KeyDataStorageDomain domain,
+                                                                 CDataWrapper&                      dataset,
+                                                                 AbstractSharedDomainCache&         restore_cache) {
+        std::vector<std::string> dataset_key;
+        dataset.getAllKey(dataset_key);
+        for (std::vector<std::string>::iterator it = dataset_key.begin();
+             it != dataset_key.end();
+             it++) {
+            restore_cache.addAttribute((SharedCacheDomain)domain,
+                                       *it,
+                                       dataset.getVariantValue(*it));
+        }
+    }
+    
+    void AbstractControlUnit::checkForRestoreOnInit() {
+        //now we can launch the restore the current input attrite, remeber that
+        //input attribute are composed by mds so the type of restore data(static conf or live) is manage at mds leve
+        //control unit in case off pply true need only to launch the restore on current input dataset set.
+        try {
+            ChaosUniquePtr<AttributeValueSharedCache> restore_cache(new AttributeValueSharedCache());
+            if (!restore_cache.get()) throw MetadataLoggingCException(getCUID(), -3, "failed to allocate restore cache", __PRETTY_FUNCTION__);
+            
+            AttributeCache& ac_src = attribute_value_shared_cache->getSharedDomain(DOMAIN_INPUT);
+            AttributeCache& ac_dst = restore_cache->getSharedDomain(DOMAIN_INPUT);
+            ac_src.copyToAttributeCache(ac_dst);
+            
+            //unitRestoreToSnapshot
+            if (unitRestoreToSnapshot(restore_cache.get())) {
+                metadataLogging(chaos::common::metadata_logging::StandardLoggingChannel::LogLevelInfo,
+                                "Restore to initilization value run successfully");
+            } else {
+                metadataLogging(chaos::common::metadata_logging::StandardLoggingChannel::LogLevelError,
+                                "Restore to initilization value has fault");
+                
+                //input attribute already already updated
+            }
+        } catch (MetadataLoggingCException& ex) {
+            throw;
+        } catch (CException& ex) {
+            MetadataLoggingCException loggable_exception(getCUID(),
+                                                         ex.errorCode,
+                                                         ex.errorMessage,
+                                                         ex.errorDomain);
+            
+            DECODE_CHAOS_EXCEPTION(loggable_exception);
+        }
+    }
+    
+    /*!
+     Restore the control unit to a precise tag
+     */
+    CDWUniquePtr AbstractControlUnit::_unitRestoreToSnapshot(CDWUniquePtr restoreParam) {
+        int err = 0;
+        //check
+        if (!restoreParam.get() || !restoreParam->hasKey(NodeDomainAndActionRPC::ACTION_NODE_RESTORE_PARAM_TAG)) return CDWUniquePtr();
+        
+        if (getServiceState() != CUStateKey::START) {
+            throw MetadataLoggingCException(getCUID(), -1, "Control Unit restore can appen only in start state", __PRETTY_FUNCTION__);
+        }
+        
+        if (!key_data_storage.get()) throw MetadataLoggingCException(getCUID(), -2, "Key data storage driver not allocated", __PRETTY_FUNCTION__);
+        
+        ChaosSharedPtr<AttributeValueSharedCache> restore_cache(new AttributeValueSharedCache());
+        if (!restore_cache.get()) throw MetadataLoggingCException(getCUID(), -3, "failed to allocate restore cache", __PRETTY_FUNCTION__);
+        
+        ChaosSharedPtr<CDataWrapper> dataset_at_tag;
+        //get tag alias
+        const std::string restore_snapshot_tag = restoreParam->getStringValue(NodeDomainAndActionRPC::ACTION_NODE_RESTORE_PARAM_TAG);
+        
+        metadataLogging(chaos::common::metadata_logging::StandardLoggingChannel::LogLevelInfo,
+                        CHAOS_FORMAT("Start restoring snapshot tag for: %1%", % restore_snapshot_tag));
+        
+        attribute_value_shared_cache->getAttributeValue(DOMAIN_SYSTEM, ControlUnitDatapackSystemKey::SETPOINT_TAG)->setStringValue(restore_snapshot_tag, true, true);
+        *attribute_value_shared_cache->getAttributeValue(DOMAIN_SYSTEM, ControlUnitDatapackSystemKey::SETPOINT_STATE)->getValuePtr<int32_t>() = ControlUnitNodeDefinitionType::SetpointRestoreStarted;  //start
+        
+        attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM).markAllAsChanged();
+        pushSystemDataset();
+        
+        //load snapshot to restore
+        if ((err = key_data_storage->loadRestorePoint(restore_snapshot_tag))) {
+            ACULERR_ << "Error loading dataset form snapshot tag: " << restore_snapshot_tag;
+            *attribute_value_shared_cache->getAttributeValue(DOMAIN_SYSTEM, ControlUnitDatapackSystemKey::SETPOINT_STATE)->getValuePtr<int32_t>() = ControlUnitNodeDefinitionType::SetpointErrorOnInit;  //error
+            
+            attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM).markAllAsChanged();
+            pushSystemDataset();
+            
+            throw MetadataLoggingCException(getCUID(), err, "Error loading dataset form snapshot", __PRETTY_FUNCTION__);
+        } else {
+            restore_cache->init(NULL);
+            
+            for (int idx = 0; idx < 4; idx++) {
+                //dataset loading sucessfull
+                dataset_at_tag = key_data_storage->getDatasetFromRestorePoint(restore_snapshot_tag,
+                                                                              (KeyDataStorageDomain)idx);
+                if (dataset_at_tag.get()) {
+                    ACULDBG_ << CHAOS_FORMAT("Dataset restored from tag %1% -> %2%", % restore_snapshot_tag % dataset_at_tag->getJSONString());
+                    //fill cache with dataset key/value
+                    fillRestoreCacheWithDatasetFromTag((KeyDataStorageDomain)idx,
+                                                       *dataset_at_tag.get(),
+                                                       *restore_cache.get());
+                }
+            }
+            *attribute_value_shared_cache->getAttributeValue(DOMAIN_SYSTEM, ControlUnitDatapackSystemKey::SETPOINT_STATE)->getValuePtr<int32_t>() = ControlUnitNodeDefinitionType::SetpointRestoreRunning;  //running
+            attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM).markAllAsChanged();
+            pushSystemDataset();
+            
+            try {
+                //unitRestoreToSnapshot
+                if (unitRestoreToSnapshot(restore_cache.get())) {
+                    metadataLogging(chaos::common::metadata_logging::StandardLoggingChannel::LogLevelInfo,
+                                    CHAOS_FORMAT("Restore for %1% has been run successfully", % restore_snapshot_tag));
+                    *attribute_value_shared_cache->getAttributeValue(DOMAIN_SYSTEM, ControlUnitDatapackSystemKey::SETPOINT_STATE)->getValuePtr<int32_t>() = ControlUnitNodeDefinitionType::SetpointRestoreReached;  //end
+                    attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM).markAllAsChanged();
+                    pushSystemDataset();
+                    
+                } else {
+                    metadataLogging(chaos::common::metadata_logging::StandardLoggingChannel::LogLevelError,
+                                    CHAOS_FORMAT("Restore for %1% has been faulted", % restore_snapshot_tag));
+                    
+                    *attribute_value_shared_cache->getAttributeValue(DOMAIN_SYSTEM, ControlUnitDatapackSystemKey::SETPOINT_STATE)->getValuePtr<int32_t>() = ControlUnitNodeDefinitionType::SetpointErrorOnStart;  //error
+                    attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM).markAllAsChanged();
+                    pushSystemDataset();
+                    //input dataset need to be update
+                    AttributeCache& ac_src = restore_cache->getSharedDomain(DOMAIN_INPUT);
+                    AttributeCache& ac_dst = attribute_value_shared_cache->getSharedDomain(DOMAIN_INPUT);
+                    ac_src.copyToAttributeCache(ac_dst);
+                }
+            } catch (MetadataLoggingCException& ex) {
+                *attribute_value_shared_cache->getAttributeValue(DOMAIN_SYSTEM, ControlUnitDatapackSystemKey::SETPOINT_STATE)->getValuePtr<int32_t>() = ControlUnitNodeDefinitionType::SetpointErrorOnRunning;  //error
+                attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM).markAllAsChanged();
+                pushSystemDataset();
+                throw;
+            } catch (CException& ex) {
+                *attribute_value_shared_cache->getAttributeValue(DOMAIN_SYSTEM, ControlUnitDatapackSystemKey::SETPOINT_STATE)->getValuePtr<int32_t>() = ControlUnitNodeDefinitionType::SetpointErrorException;  //error
+                attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM).markAllAsChanged();
+                pushSystemDataset();
+                MetadataLoggingCException loggable_exception(getCUID(),
+                                                             ex.errorCode,
+                                                             ex.errorMessage,
+                                                             ex.errorDomain);
+                
+                DECODE_CHAOS_EXCEPTION(loggable_exception);
+            }
+            
+            //end
+            try {
+                restore_cache->deinit();
+            } catch (MetadataLoggingCException& ex) {
+                throw;
+            } catch (CException& ex) {
+                MetadataLoggingCException loggable_exception(getCUID(),
+                                                             ex.errorCode,
+                                                             ex.errorMessage,
+                                                             ex.errorDomain);
+                DECODE_CHAOS_EXCEPTION(loggable_exception);
+            } catch (...) {
+                ACULERR_ << "General error on deinit restore cache";
+            }
+            
+            //! clear snapshoted dataset to free memeory
+            key_data_storage->clearRestorePoint(restore_snapshot_tag);
+        }
+        metadataLogging(chaos::common::metadata_logging::StandardLoggingChannel::LogLevelInfo,
+                        CHAOS_FORMAT("End restoring snapshot tag for: %1%", % restore_snapshot_tag));
+        return CDWUniquePtr();
+    }
+    
+    /*
+     Receive the event for set the dataset input element
+     */
+    CDWUniquePtr AbstractControlUnit::_setDatasetAttribute(CDWUniquePtr dataset_attribute_values) {
+        CDWUniquePtr result;
+        try {
+            if (!dataset_attribute_values.get()) {
+                throw MetadataLoggingCException(getCUID(), -1, "No Input parameter", __PRETTY_FUNCTION__);
+            }
+            if (SWEService::getServiceState() == CUStateKey::DEINIT) {
+                throw MetadataLoggingCException(getCUID(), -3, "The Control Unit is in deinit state", __PRETTY_FUNCTION__);
+            }
+            //send dataset attribute change pack to control unit implementation
+            result = setDatasetAttribute(MOVE(dataset_attribute_values));
+        } catch (CException& ex) {
+            throw;
+        }
+        return result;
+    }
+#pragma mark State Machine method
+    // Startable Service method
+    void AbstractControlUnit::init(void* init_data) {
+        //allocate metadata loggin channel for alarm
+        alarm_logging_channel = (AlarmLoggingChannel*)MetadataLoggingManager::getInstance()->getChannel("AlarmLoggingChannel");
+        if (alarm_logging_channel == NULL) {
+            LOG_AND_TROW(ACULERR_, -1, "Alarm logging channel not found");
+        }
+        
+        standard_logging_channel = (StandardLoggingChannel*)MetadataLoggingManager::getInstance()->getChannel("StandardLoggingChannel");
+        if (standard_logging_channel == NULL) {
+            LOG_AND_TROW(ACULERR_, -2, "Standard logging channel not found");
+        }
+        standard_logging_channel->setLogLevel(common::metadata_logging::StandardLoggingChannel::LogLevelInfo);
+        //the init of the implementation unit goes after the infrastructure one
+        doInitSMCheckList();
+    }
+    
+    // Startable Service method
+    void AbstractControlUnit::start() {
+        doStartSMCheckList();
+    }
+    
+    // Startable Service method
+    void AbstractControlUnit::stop() {
+        redoStartSMCheckList();
+    }
+    
+    // Startable Service method
+    void AbstractControlUnit::deinit() {
+        redoInitSMCheckList();
+        if (alarm_logging_channel) {
+            MetadataLoggingManager::getInstance()->releaseChannel(alarm_logging_channel);
+            alarm_logging_channel = NULL;
+        }
+        
+        if (standard_logging_channel) {
+            MetadataLoggingManager::getInstance()->releaseChannel(standard_logging_channel);
+            standard_logging_channel = NULL;
+        }
+    }
+    
+    //! State machine is gone into recoverable error
+    void AbstractControlUnit::recoverableErrorFromState(int last_state, chaos::CException& ex) {
+        ACULERR_ << "recoverableErrorFromState with state:" << last_state;
+        
+        //update healt tstatus to report recoverable error
+        HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
+                                                        NodeHealtDefinitionKey::NODE_HEALT_STATUS,
+                                                        NodeHealtDefinitionValue::NODE_HEALT_STATUS_RERROR,
+                                                        false);
+        HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
+                                                        NodeHealtDefinitionKey::NODE_HEALT_LAST_ERROR_CODE,
+                                                        ex.errorCode,
+                                                        false);
+        HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
+                                                        NodeHealtDefinitionKey::NODE_HEALT_LAST_ERROR_MESSAGE,
+                                                        ex.errorMessage,
+                                                        false);
+        HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
+                                                        NodeHealtDefinitionKey::NODE_HEALT_LAST_ERROR_DOMAIN,
+                                                        ex.errorDomain,
+                                                        true);
+        //we stop the run action
+        CHAOS_NOT_THROW(stop();)
+    }
+    
+    //! State machine is gone into recoverable error
+    bool AbstractControlUnit::beforeRecoverErrorFromState(int last_state) {
+        ACULERR_ << "beforeRecoverErrorFromState with state:" << last_state;
+        std::string last_state_str;
+        switch (last_state) {
+            case CUStateKey::INIT:
+                last_state_str = NodeHealtDefinitionValue::NODE_HEALT_STATUS_INIT;
+                break;
+            case CUStateKey::DEINIT:
+                last_state_str = NodeHealtDefinitionValue::NODE_HEALT_STATUS_DEINIT;
+                break;
+            case CUStateKey::START:
+                last_state_str = NodeHealtDefinitionValue::NODE_HEALT_STATUS_START;
+                break;
+            case CUStateKey::STOP:
+                last_state_str = NodeHealtDefinitionValue::NODE_HEALT_STATUS_STOP;
+                break;
+        }
+        HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
+                                                        NodeHealtDefinitionKey::NODE_HEALT_STATUS,
+                                                        last_state_str,
+                                                        false);
+        HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
+                                                        NodeHealtDefinitionKey::NODE_HEALT_LAST_ERROR_CODE,
+                                                        0,
+                                                        false);
+        HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
+                                                        NodeHealtDefinitionKey::NODE_HEALT_LAST_ERROR_MESSAGE,
+                                                        "",
+                                                        false);
+        HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
+                                                        NodeHealtDefinitionKey::NODE_HEALT_LAST_ERROR_DOMAIN,
+                                                        "",
+                                                        true);
+        //restart the cotnrol unit
+        CHAOS_NOT_THROW(start();)
+        return true;
+    }
+    
+    //! State machine is gone into recoverable error
+    void AbstractControlUnit::recoveredToState(int last_state) {
+        ACULERR_ << "recoveredToState with state:" << last_state;
+    }
+    
+    //! State machine is gone into an unrecoverable error
+    void AbstractControlUnit::fatalErrorFromState(int last_state, chaos::CException& ex) {
+        ACULERR_ << "fatalErrorFromState with state:" << last_state;
+        switch (last_state) {
+            case CUStateKey::INIT:
+                //deinit
+                //CHAOS_NOT_THROW(redoInitSMCheckList(false);)
+                deinit();
+                CHAOS_NOT_THROW(redoInitRpCheckList(false);)
+                break;
+            case CUStateKey::DEINIT:
+                
+                break;
+            case CUStateKey::START:
+                //stop
+                //CHAOS_NOT_THROW(redoStartSMCheckList(false);)
+                stop();
+                CHAOS_NOT_THROW(redoStartRpCheckList(false);)
+                //deinit
+                //CHAOS_NOT_THROW(redoInitSMCheckList(false);)
+                deinit();
+                CHAOS_NOT_THROW(redoInitRpCheckList(false);)
+                break;
+            case CUStateKey::STOP:
+                break;
+        }  //update healt tstatus to report recoverable error
+        HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
+                                                        NodeHealtDefinitionKey::NODE_HEALT_STATUS,
+                                                        NodeHealtDefinitionValue::NODE_HEALT_STATUS_FERROR,
+                                                        false);
+        HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
+                                                        NodeHealtDefinitionKey::NODE_HEALT_LAST_ERROR_CODE,
+                                                        ex.errorCode,
+                                                        false);
+        HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
+                                                        NodeHealtDefinitionKey::NODE_HEALT_LAST_ERROR_MESSAGE,
+                                                        ex.errorMessage,
+                                                        false);
+        HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
+                                                        NodeHealtDefinitionKey::NODE_HEALT_LAST_ERROR_DOMAIN,
+                                                        ex.errorDomain,
+                                                        true);
+    }
+    
+    void AbstractControlUnit::fillCachedValueVector(AttributeCache&               attribute_cache,
+                                                    std::vector<AttributeValue*>& cached_value) {
+        for (int idx = 0;
+             idx < attribute_cache.getNumberOfAttributes();
+             idx++) {
+            cached_value.push_back(attribute_cache.getValueSettingForIndex(idx));
+        }
+    }
+    
+    void AbstractControlUnit::initAttributeOnSharedAttributeCache(SharedCacheDomain         domain,
+                                                                  std::vector<std::string>& attribute_names) {
+        //add input attribute to shared setting
+        CHAOS_ASSERT(attribute_value_shared_cache)
+        RangeValueInfo  attributeInfo;
+        AttributeCache& attribute_setting = attribute_value_shared_cache->getSharedDomain(domain);
+        
+        for (int idx = 0;
+             idx < attribute_names.size();
+             idx++) {
+            attributeInfo.reset();
+            
+            // retrive the attribute description from the device database
+            DatasetDB::getAttributeRangeValueInfo(attribute_names[idx], attributeInfo);
+            
+            // add the attribute to the shared setting object
+            attribute_setting.addAttribute(attribute_names[idx], attributeInfo.maxSize, attributeInfo.valueType, attributeInfo.binType);
+            
+            if (!attributeInfo.defaultValue.size()) continue;
+            
+            //setting value using index (the index into the sharedAttributeSetting are sequencial to the inserted order)
+            try {
+                switch (attributeInfo.valueType) {
+                    case DataType::TYPE_BOOLEAN: {
+                        bool val = boost::lexical_cast<bool>(attributeInfo.defaultValue);
+                        attribute_setting.setValueForAttribute(idx, &val, sizeof(bool));
+                        ACULDBG_ << "Init attribute:" << attribute_names[idx]<<" to:"<<val;
+                        break;
+                    }
+                    case DataType::TYPE_DOUBLE: {
+                        double val = boost::lexical_cast<double>(attributeInfo.defaultValue);
+                        attribute_setting.setValueForAttribute(idx, &val, sizeof(double));
+                        ACULDBG_ << "Init attribute:" << attribute_names[idx]<<" to:"<<val;
+                        break;
+                    }
+                    case DataType::TYPE_INT32: {
+                        int32_t val = strtoul(attributeInfo.defaultValue.c_str(), 0, 0);  //boost::lexical_cast<int32_t>(attributeInfo.defaultValue);
+                        attribute_setting.setValueForAttribute(idx, &val, sizeof(int32_t));
+                        ACULDBG_ << "Init attribute:" << attribute_names[idx]<<" to:"<<val;
+                        break;
+                    }
+                    case DataType::TYPE_INT64: {
+                        int64_t val = strtoll(attributeInfo.defaultValue.c_str(), 0, 0);  //boost::lexical_cast<int64_t>(attributeInfo.defaultValue);
+                        attribute_setting.setValueForAttribute(idx, &val, sizeof(int64_t));
+                        ACULDBG_ << "Init attribute:" << attribute_names[idx]<<" to:"<<val;
+                        break;
+                    }
+                    case DataType::TYPE_CLUSTER: {
+                        CDataWrapper tmp;
+                        tmp.setSerializedJsonData(attributeInfo.defaultValue.c_str());
+                        attribute_setting.setValueForAttribute(idx, tmp);
+                        ACULDBG_ << "Init attribute:" << attribute_names[idx]<<" to:"<<attributeInfo.defaultValue.c_str();
+                    }
+                    case DataType::TYPE_STRING: {
+                        const char* val = attributeInfo.defaultValue.c_str();
+                        attribute_setting.setValueForAttribute(idx, val, (uint32_t)attributeInfo.defaultValue.size());
+                        ACULDBG_ << "Init attribute:" << attribute_names[idx]<<" to:"<<val;
+                        break;
+                    }
+                    case DataType::TYPE_BYTEARRAY: {
+                        ACULDBG_ << "Binary default setting has not been yet managed";
+                        break;
+                    }
+                    default:
+                        break;
+                }
+            } catch (boost::bad_lexical_cast const& e) {
+                ACULERR_ << e.what();
+            }
+        }
+    }
+    
+    void AbstractControlUnit::completeOutputAttribute() {
+        ACULDBG_ << "Complete the shared cache output attribute";
+        AttributeCache& domain_attribute_setting = attribute_value_shared_cache->getSharedDomain(DOMAIN_OUTPUT);
+        
+        //add timestamp
+        domain_attribute_setting.addAttribute(DataPackCommonKey::DPCK_TIMESTAMP, sizeof(uint64_t), DataType::TYPE_INT64);
+        timestamp_acq_cached_value = domain_attribute_setting.getValueSettingForIndex(domain_attribute_setting.getIndexForName(DataPackCommonKey::DPCK_TIMESTAMP));
+        
+        domain_attribute_setting.addAttribute(DataPackCommonKey::DPCK_HIGH_RESOLUTION_TIMESTAMP, sizeof(uint64_t), DataType::TYPE_INT64);
+        timestamp_hw_acq_cached_value = domain_attribute_setting.getValueSettingForIndex(domain_attribute_setting.getIndexForName(DataPackCommonKey::DPCK_HIGH_RESOLUTION_TIMESTAMP));
+    }
+    
+    void AbstractControlUnit::completeInputAttribute() {
+    }
+    
+    AbstractSharedDomainCache* AbstractControlUnit::_getAttributeCache() {
+        return attribute_value_shared_cache;
+    }
+    
+    void AbstractControlUnit::initSystemAttributeOnSharedAttributeCache() {
+        AttributeCache& domain_attribute_setting = attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM);
+        
+        //add schedule time
+        ACULDBG_ << "Adding system attribute on shared cache";
+        domain_attribute_setting.addAttribute(ControlUnitDatapackSystemKey::THREAD_SCHEDULE_DELAY, 0, DataType::TYPE_INT64);
+        thread_schedule_daly_cached_value = domain_attribute_setting.getValueSettingForIndex(domain_attribute_setting.getIndexForName(ControlUnitDatapackSystemKey::THREAD_SCHEDULE_DELAY));
+        
+        //add busy state
+        domain_attribute_setting.addAttribute("busy", 0, DataType::TYPE_BOOLEAN);
+        
+        //add bypass state
+        domain_attribute_setting.addAttribute(ControlUnitDatapackSystemKey::BYPASS_STATE, 0, DataType::TYPE_BOOLEAN);
+        
+        //add AlarmCU state
+        domain_attribute_setting.addAttribute(chaos::ControlUnitDatapackSystemKey::CU_ALRM_LEVEL, 0, DataType::TYPE_INT32);
+        
+        //add AlarmDev state
+        domain_attribute_setting.addAttribute(chaos::ControlUnitDatapackSystemKey::DEV_ALRM_LEVEL, 0, DataType::TYPE_INT32);
+        
+        //add burst operation state
+        domain_attribute_setting.addAttribute(ControlUnitDatapackSystemKey::BURST_STATE, 0, DataType::TYPE_BOOLEAN);
+        
+        //add burst operation tag
+        domain_attribute_setting.addAttribute(ControlUnitDatapackSystemKey::BURST_TAG, 0, DataType::TYPE_STRING);
+        
+        //add setpoint operation state
+        domain_attribute_setting.addAttribute(ControlUnitDatapackSystemKey::SETPOINT_STATE, 0, DataType::TYPE_INT32);
+        
+        //add setpoint operation tag
+        domain_attribute_setting.addAttribute(ControlUnitDatapackSystemKey::SETPOINT_TAG, 0, DataType::TYPE_STRING);
+        
+        //add storage type
+        domain_attribute_setting.addAttribute(DataServiceNodeDefinitionKey::DS_STORAGE_TYPE, 0, DataType::TYPE_INT32);
+        
+        //add live time
+        domain_attribute_setting.addAttribute(DataServiceNodeDefinitionKey::DS_STORAGE_LIVE_TIME, 0, DataType::TYPE_INT64);
+        
+        //add history time
+        domain_attribute_setting.addAttribute(DataServiceNodeDefinitionKey::DS_STORAGE_HISTORY_TIME, 0, DataType::TYPE_INT64);
+        
+        //add history time
+        domain_attribute_setting.addAttribute(DataServiceNodeDefinitionKey::DS_STORAGE_HISTORY_TIME, 0, DataType::TYPE_INT64);
+        
+        //add unit type
+        domain_attribute_setting.addAttribute(DataPackSystemKey::DP_SYS_UNIT_TYPE, (uint32_t)control_unit_type.size(), DataType::TYPE_STRING);
+        char* str_ptr = domain_attribute_setting.getValueSettingForIndex(domain_attribute_setting.getIndexForName(DataPackSystemKey::DP_SYS_UNIT_TYPE))->getValuePtr<char>();
+        strncpy(str_ptr, control_unit_type.c_str(), control_unit_type.size());
+    }
+    
+    /*
+     Get the current control unit state
+     */
+    CDWUniquePtr AbstractControlUnit::_getState(CDWUniquePtr getStatedParam) {
+        CreateNewDataWrapper(result, );
+        result->addInt32Value(CUStateKey::CONTROL_UNIT_STATE, static_cast<CUStateKey::ControlUnitState>(SWEService::getServiceState()));
+        return result;
+    }
+    
+    CDWUniquePtr AbstractControlUnit::_submitStorageBurst(CDWUniquePtr data) {
+        common::data::structured::DatasetBurstSDWrapper db_sdw;
+        db_sdw.deserialize(data.get());
+        DatasetBurstShrdPtr burst = ChaosMakeSharedPtr<DatasetBurst>(db_sdw());
+        
+        if (burst->type == chaos::ControlUnitNodeDefinitionType::DSStorageBurstTypeUndefined) {
+            ACULERR_ << CHAOS_FORMAT("The type is mandatory for burst %1%", % data->getJSONString());
+            return CDWUniquePtr();
+        }
+        if (!burst->value.isValid()) {
+            ACULERR_ << CHAOS_FORMAT("The value is mandatory for burst %1%", % data->getJSONString());
+            return CDWUniquePtr();
+        }
+        ACULDBG_ << "Enabling burst:" << data->getCompliantJSONString();
+        LQueueBurstWriteLock wl = burst_queue.getWriteLockObject();
+        burst_queue().push(burst);
+        return CDWUniquePtr();
+    }
+    
+    CDWUniquePtr AbstractControlUnit::_datasetTagManagement(CDWUniquePtr data) {
+        CHECK_ASSERTION_THROW_AND_LOG(data.get() != NULL, ACULERR_, -1, "No parameter found");
+        if (data->hasKey(ControlUnitNodeDomainAndActionRPC::ACTION_DATASET_TAG_MANAGEMENT_ADD_LIST)) {
+            CHECK_KEY_THROW_AND_LOG(data,
+                                    ControlUnitNodeDomainAndActionRPC::ACTION_DATASET_TAG_MANAGEMENT_ADD_LIST,
+                                    ACULERR_,
+                                    -2,
+                                    CHAOS_FORMAT("The key %1% need to be a vector", % ControlUnitNodeDomainAndActionRPC::ACTION_DATASET_TAG_MANAGEMENT_ADD_LIST));
+            ChaosStringSet                 ss;
+            CMultiTypeDataArrayWrapperSPtr vec = data->getVectorValue(ControlUnitNodeDomainAndActionRPC::ACTION_DATASET_TAG_MANAGEMENT_REMOVE_LIST);
+            for (int idx = 0; idx < vec->size(); idx++) {
+                if (vec->isStringElementAtIndex(idx)) {
+                    ss.insert(vec->getStringElementAtIndex(idx));
+                }
+            }
+            key_data_storage->addTag(ss);
+        }
+        
+        if (data->hasKey(ControlUnitNodeDomainAndActionRPC::ACTION_DATASET_TAG_MANAGEMENT_REMOVE_LIST)) {
+            CHECK_KEY_THROW_AND_LOG(data,
+                                    ControlUnitNodeDomainAndActionRPC::ACTION_DATASET_TAG_MANAGEMENT_REMOVE_LIST,
+                                    ACULERR_,
+                                    -3,
+                                    CHAOS_FORMAT("The key %1% need to be a vector", % ControlUnitNodeDomainAndActionRPC::ACTION_DATASET_TAG_MANAGEMENT_REMOVE_LIST));
+            ChaosStringSet                 ss;
+            CMultiTypeDataArrayWrapperSPtr vec = data->getVectorValue(ControlUnitNodeDomainAndActionRPC::ACTION_DATASET_TAG_MANAGEMENT_REMOVE_LIST);
+            for (int idx = 0; idx < vec->size(); idx++) {
+                if (vec->isStringElementAtIndex(idx)) {
+                    ss.insert(vec->getStringElementAtIndex(idx));
+                }
+            }
+            key_data_storage->removeTag(ss);
+        }
+        
+        return CDWUniquePtr();
+    }
+    
+    /*
+     Get the current control unit state
+     */
+    CDWUniquePtr AbstractControlUnit::_getInfo(CDWUniquePtr getStatedParam) {
+        CreateNewDataWrapper(stateResult, );
+        //set the string representing the type of the control unit
+        stateResult->addStringValue(NodeDefinitionKey::NODE_TYPE, NodeType::NODE_TYPE_CONTROL_UNIT);
+        stateResult->addStringValue(NodeDefinitionKey::NODE_SUB_TYPE, control_unit_type);
+        return stateResult;
+    }
+    
+    void AbstractControlUnit::_updateAcquistionTimestamp(uint64_t alternative_ts) {
+        *timestamp_acq_cached_value->getValuePtr<uint64_t>() = alternative_ts / 1000;
+        if (!use_custom_high_resolution_timestamp) {
+            *timestamp_hw_acq_cached_value->getValuePtr<uint64_t>() = alternative_ts;
+        }
+    }
+    
+    void AbstractControlUnit::useCustomHigResolutionTimestamp(bool _use_custom_high_resolution_timestamp) {
+        use_custom_high_resolution_timestamp = _use_custom_high_resolution_timestamp;
+    }
+    
+    void AbstractControlUnit::setHigResolutionAcquistionTimestamp(uint64_t high_resolution_timestamp) {
+        if (use_custom_high_resolution_timestamp) {
+            *timestamp_hw_acq_cached_value->getValuePtr<uint64_t>() = high_resolution_timestamp;
+        }
+    }
+    
+    void AbstractControlUnit::_updateRunScheduleDelay(uint64_t new_scehdule_delay) {
+        if (*thread_schedule_daly_cached_value->getValuePtr<uint64_t>() == new_scehdule_delay) return;
+        //we need to update the value
+        *thread_schedule_daly_cached_value->getValuePtr<uint64_t>() = new_scehdule_delay;
+        thread_schedule_daly_cached_value->markAsChanged();
+    }
+    
+    //!timer for update push metric
+    void AbstractControlUnit::_updatePushRateMetric() {
+        uint64_t rate_acq_ts    = TimingUtil::getTimeStamp();
+        double   time_offset    = (double(rate_acq_ts - last_push_rate_grap_ts)) / 1000.0;     //time in seconds
+        double   output_ds_rate = (time_offset > 0) ? push_dataset_counter / time_offset : 0;  //rate in seconds
+        int32_t   output_size_rate = (push_dataset_counter > 0) ? push_dataset_size / push_dataset_counter : 0;  //rate in seconds
+        
+        HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
+                                                        ControlUnitHealtDefinitionValue::CU_HEALT_OUTPUT_DATASET_PUSH_RATE,
+                                                        output_ds_rate);
+        HealtManager::getInstance()->addNodeMetricValue(control_unit_id,
+                                                        ControlUnitHealtDefinitionValue::CU_HEALT_OUTPUT_DATASET_PUSH_SIZE,
+                                                        output_size_rate);
+        
+        //keep track of acquire timestamp
+        last_push_rate_grap_ts = rate_acq_ts;
+        //reset pushe count
+        push_dataset_counter = 0;
+        push_dataset_size=0;
+    }
+    
+    //!put abstract control unit state machine in recoverable error
+    void AbstractControlUnit::_goInRecoverableError(chaos::CException recoverable_exception) {
+        //change state machine
+        if (SWEService::goInRecoverableError(this, recoverable_exception, "RTAbstractControlUnit", __PRETTY_FUNCTION__)) {
+            //update healt the status to report recoverable error
+        }
+    }
+    
+    //!put abstract control unit state machine in fatal error
+    void AbstractControlUnit::_goInFatalError(chaos::CException recoverable_exception) {
+        //change state machine
+        if (SWEService::goInFatalError(this, recoverable_exception, "RTAbstractControlUnit", __PRETTY_FUNCTION__)) {
+        }
+    }
+    
+    void AbstractControlUnit::_completeDatasetAttribute() {
+        //add global alarm checn
+        /*
+         DatasetDB::addAttributeToDataSet(stateVariableEnumToName(StateVariableTypeAlarmCU),
+         "Activated when some warning has been issued",
+         DataType::TYPE_INT32,
+         DataType::Output);
+         DatasetDB::addAttributeToDataSet(stateVariableEnumToName(StateVariableTypeAlarmDEV),
+         "Activated when some alarm has been issued",
+         DataType::TYPE_INT32,
+         DataType::Output);
+         */
+    }
+    
+    void AbstractControlUnit::_setBypassState(bool bypass_stage,
+                                              bool high_priority) {
+        DrvMsg cmd;
+        cmd.opcode = bypass_stage ? OpcodeType::OP_SET_BYPASS : OpcodeType::OP_CLEAR_BYPASS;
+        //broadcast bypass to all driver instances allocated by control unit
+        for (VInstantitedDriverIterator it  = accessor_instances.begin(),
+             end = accessor_instances.end();
+             it != end;
+             it++) {
+            (*it)->send(&cmd, (high_priority ? 1000 : 0));
+        }
+        //update dateset
+        *attribute_value_shared_cache->getAttributeValue(DOMAIN_SYSTEM, ControlUnitDatapackSystemKey::BYPASS_STATE)->getValuePtr<bool>() = bypass_stage;
+    }
+    
+    //!handler calledfor restor a control unit to a determinate point
+    bool AbstractControlUnit::unitRestoreToSnapshot(AbstractSharedDomainCache* const snapshot_cache) {
+        return true;
+    }
+    
+    //! this andler is called befor the input attribute will be updated
+    void AbstractControlUnit::unitInputAttributePreChangeHandler() {}
+    
+    //! attribute change handler
+    /*!
+     the handle is fired after the input attribute cache as been update triggere
+     by the rpc request for attribute change.
+     */
+    void AbstractControlUnit::unitInputAttributeChangedHandler() {}
+    
+#define CHECK_FOR_RANGE_VALUE(t, v, attr_name)                                                                            \
+t max, min;                                                                                                             \
+if (attributeInfo.maxRange.compare(0, 2, "0x") == 0) {                                                                  \
+max = strtoll(attributeInfo.maxRange.c_str(), 0, 0);                                                                  \
+} else {                                                                                                                \
+max = attributeInfo.maxRange.size() ? boost::lexical_cast<t>(attributeInfo.maxRange) : std::numeric_limits<t>::max(); \
+}                                                                                                                       \
+if (attributeInfo.minRange.compare(0, 2, "0x") == 0) {                                                                  \
+min = strtoll(attributeInfo.minRange.c_str(), 0, 0);                                                                  \
+} else {                                                                                                                \
+min = attributeInfo.minRange.size() ? boost::lexical_cast<t>(attributeInfo.minRange) : std::numeric_limits<t>::min(); \
+}                                                                                                                       \
+if (v < min || v > max) throw MetadataLoggingCException(getCUID(), -1, boost::str(boost::format("Invalid value (%1%) [Min:%2% Max:%3%] for attribute %4%") % v % attributeInfo.minRange % attributeInfo.maxRange % attr_name).c_str(), __PRETTY_FUNCTION__);
+    
+#define CHECK_FOR_STRING_RANGE_VALUE(v, attr_name)                                                                                                                                                                                                                                                      \
+if (attributeInfo.minRange.size() && v < attributeInfo.minRange) throw MetadataLoggingCException(getCUID(), -1, boost::str(boost::format("Invalid value (%1%) [max:%2% Min:%3%] for attribute %4%") % v % attr_name % attributeInfo.minRange % attributeInfo.maxRange).c_str(), __PRETTY_FUNCTION__); \
+if (attributeInfo.maxRange.size() && v > attributeInfo.maxRange) throw MetadataLoggingCException(getCUID(), -1, boost::str(boost::format("Invalid value (%1%) [max:%2% Min:%3%] for attribute %4%") % v % attr_name % attributeInfo.minRange % attributeInfo.maxRange).c_str(), __PRETTY_FUNCTION__);
+    
+    CDWUniquePtr AbstractControlUnit::setDatasetAttribute(CDWUniquePtr dataset_attribute_values) {
+        CHAOS_ASSERT(dataset_attribute_values.get())
+        ChaosSharedPtr<SharedCacheLockDomain> w_lock = attribute_value_shared_cache->getLockOnDomain(DOMAIN_INPUT, true);
+        w_lock->lock();
+        
+        RangeValueInfo           attributeInfo;
+        std::vector<std::string> in_attribute_name;
+        
+        try {
+            //call pre handler
+            unitInputAttributePreChangeHandler();
+            
+            //first call attribute handler
+            dataset_attribute_manager.executeHandlers(dataset_attribute_values.get());
+            
+            //get all input attribute name for input and bidirectional directions
+            getDatasetAttributesName(DataType::Input, in_attribute_name);
+            getDatasetAttributesName(DataType::Bidirectional, in_attribute_name);
+            attribute_value_shared_cache->getAttributeNames(DOMAIN_CUSTOM,in_attribute_name);
+            if (dataset_attribute_values->hasKey(NodeDefinitionKey::NODE_UNIQUE_ID)) {
+                //get the contrl unit id
+                std::string node_id = dataset_attribute_values->getStringValue(NodeDefinitionKey::NODE_UNIQUE_ID);
+                //compare the message device id and the local
+                for (std::vector<std::string>::iterator iter = in_attribute_name.begin();
+                     iter != in_attribute_name.end();
+                     iter++) {
+                    //execute attribute handler
+                    const char* attr_name = iter->c_str();
+                    
+                    //check if the attribute name is present
+                    if (dataset_attribute_values->hasKey(attr_name)) {
+                        //check if attribute has been accepted
+                        if (dataset_attribute_manager.getHandlerResult(*iter) == false) continue;
+                        
+                        AttributeValue* attribute_cache_value = attribute_value_shared_cache->getAttributeValue(DOMAIN_INPUT, iter->c_str());
+                        
+                        //get attribute info
+                        getAttributeRangeValueInfo(*iter, attributeInfo);
+                        
+                        //call handler
+                        switch (attribute_cache_value->type) {
+                            case DataType::TYPE_BOOLEAN: {
+                                bool bv = dataset_attribute_values->getBoolValue(attr_name);
+                                attribute_cache_value->setValue(&bv, sizeof(bool));
+                                break;
+                            }
+                            case DataType::TYPE_INT32: {
+                                int32_t i32v = dataset_attribute_values->getInt32Value(attr_name);
+                                CHECK_FOR_RANGE_VALUE(int32_t, i32v, attr_name)
+                                attribute_cache_value->setValue(&i32v, sizeof(int32_t));
+                                break;
+                            }
+                            case DataType::TYPE_INT64: {
+                                int64_t i64v = dataset_attribute_values->getInt64Value(attr_name);
+                                CHECK_FOR_RANGE_VALUE(int64_t, i64v, attr_name)
+                                attribute_cache_value->setValue(&i64v, sizeof(int64_t));
+                                break;
+                            }
+                            case DataType::TYPE_DOUBLE: {
+                                double dv = dataset_attribute_values->getDoubleValue(attr_name);
+                                CHECK_FOR_RANGE_VALUE(double, dv, attr_name)
+                                attribute_cache_value->setValue(&dv, sizeof(double));
+                                break;
+                            }
+                                
+                            case DataType::TYPE_CLUSTER: {
+                                ChaosUniquePtr<CDataWrapper> str = dataset_attribute_values->getCSDataValue(attr_name);
+                                try {
+                                    if (str.get()) {
+                                        attribute_cache_value->setValue(*(str.get()));
+                                    }
+                                } catch (...) {
+                                    throw MetadataLoggingCException(getCUID(), -1, boost::str(boost::format("Invalid Json format ")).c_str(), __PRETTY_FUNCTION__);
+                                }
+                                break;
+                            }
+                            case DataType::TYPE_STRING: {
+                                std::string str = dataset_attribute_values->getStringValue(attr_name);
+                                CHECK_FOR_STRING_RANGE_VALUE(str, attr_name)
+                                attribute_cache_value->setValue(str.c_str(), (uint32_t)str.size());
+                                break;
+                            }
+                            case DataType::TYPE_BYTEARRAY: {
+                                uint32_t    bin_size = 0;
+                                const char* binv     = dataset_attribute_values->getBinaryValue(attr_name, bin_size);
+                                attribute_cache_value->setValue(binv, bin_size);
+                                break;
+                            }
+                            default:
+                                break;
+                        }
+                    }
+                }
+                //push the input attribute dataset
+                pushInputDataset();
+            }
+            
+            //inform the subclass for the change
+            unitInputAttributeChangedHandler();
+        } catch (CException& ex) {
+            //inform the subclass for the change
+            unitInputAttributeChangedHandler();
+            throw;
+        }
+        return CDWUniquePtr();
+    }
+    
+    /*
+     Update the configuration for all descendant tree in the Control Unit class structure
+     */
+    CDWUniquePtr AbstractControlUnit::updateConfiguration(CDWUniquePtr update_pack) {
+        //check to see if the device can ben initialized
+        if (SWEService::getServiceState() != chaos::CUStateKey::INIT &&
+            SWEService::getServiceState() != chaos::CUStateKey::START) {
+            ACULAPP_ << "device:" << DatasetDB::getDeviceID() << " not initialized";
+            throw MetadataLoggingCException(getCUID(), -3, "Device Not Initilized", __PRETTY_FUNCTION__);
+        }
+        
+        PropertyGroupVectorSDWrapper pg_sdw;
+        pg_sdw.serialization_key = "property";
+        pg_sdw.deserialize(update_pack.get());
+        
+        //update the property
+        PropertyCollector::applyValue(pg_sdw());
+        key_data_storage->updateConfiguration(update_pack.get());
+        //mark all cache as changed
+        attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM).markAllAsChanged();
+        
+        pushSystemDataset();
+        return CDWUniquePtr();
+    }
+    
+    bool AbstractControlUnit::propertyChangeHandler(const std::string&  group_name,
+                                                    const std::string&  property_name,
+                                                    const CDataVariant& property_value) {
+        ACULDBG_ << CHAOS_FORMAT("Update property request for %1%[%2%] with value %3%", % property_name % group_name % property_value.asString());
+        return true;
+    }
+    
+    void AbstractControlUnit::propertyUpdatedHandler(const std::string&  group_name,
+                                                     const std::string&  property_name,
+                                                     const CDataVariant& old_value,
+                                                     const CDataVariant& new_value) {
+        if (group_name.compare("property_abstract_control_unit") == 0) {
+            //update property on driver
+            key_data_storage->updateConfiguration(property_name, new_value);
+            //reflect modification on dataset
+            if (property_name.compare(ControlUnitDatapackSystemKey::BYPASS_STATE) == 0) {
+                _setBypassState(new_value.asBool());
+            } else if (property_name.compare(DataServiceNodeDefinitionKey::DS_STORAGE_TYPE) == 0) {
+                *attribute_value_shared_cache->getAttributeValue(DOMAIN_SYSTEM, DataServiceNodeDefinitionKey::DS_STORAGE_TYPE)->getValuePtr<int32_t>() = new_value.asInt32();
+            } else if (property_name.compare(DataServiceNodeDefinitionKey::DS_STORAGE_LIVE_TIME) == 0) {
+                *attribute_value_shared_cache->getAttributeValue(DOMAIN_SYSTEM, DataServiceNodeDefinitionKey::DS_STORAGE_LIVE_TIME)->getValuePtr<uint64_t>() = new_value.asUInt64();
+            } else if (property_name.compare(DataServiceNodeDefinitionKey::DS_STORAGE_HISTORY_TIME) == 0) {
+                *attribute_value_shared_cache->getAttributeValue(DOMAIN_SYSTEM, DataServiceNodeDefinitionKey::DS_STORAGE_HISTORY_TIME)->getValuePtr<uint64_t>() = new_value.asUInt64();
+            }
+        }
+    }
+    
+    //! return the accessor by an index
+    /*
+     The index parameter correspond to the order that the driver infromation are
+     added by the unit implementation into the function AbstractControlUnit::unitDefineDriver.
+     */
+    DriverAccessor* AbstractControlUnit::getAccessoInstanceByIndex(int idx) {
+        if (idx >= accessor_instances.size()) return NULL;
+        return accessor_instances[idx];
+    }
+    
+    int AbstractControlUnit::pushOutputDataset() {
+        int                                   err                    = 0;
+        AttributeCache&                       output_attribute_cache = attribute_value_shared_cache->getSharedDomain(DOMAIN_OUTPUT);
+        ChaosSharedPtr<SharedCacheLockDomain> r_lock                 = attribute_value_shared_cache->getLockOnDomain(DOMAIN_OUTPUT, false);
+        r_lock->lock();
+        
+        //check if something as changed
+        if (!output_attribute_cache.hasChanged()) {return err;}
+        
+        CDWShrdPtr output_attribute_dataset = key_data_storage->getNewDataPackForDomain(KeyDataStorageDomainOutput);
+        if (!output_attribute_dataset.get()) {
+            ACULERR_ << " Cannot allocate packet.. err:"<<err;
+            return err;
+        }
+        output_attribute_dataset->addInt64Value(ControlUnitDatapackCommonKey::RUN_ID, run_id);
+        output_attribute_dataset->addInt64Value(DataPackCommonKey::DPCK_TIMESTAMP, *timestamp_acq_cached_value->getValuePtr<uint64_t>());
+        output_attribute_dataset->addInt64Value(DataPackCommonKey::DPCK_HIGH_RESOLUTION_TIMESTAMP, *timestamp_hw_acq_cached_value->getValuePtr<uint64_t>());
+        
+        //add all other output channel
+        for (int idx = 0;
+             idx < ((int)cache_output_attribute_vector.size()) - 1;  //the device id and timestamp in added out of this list
+             idx++) {
+            //
+            AttributeValue* value_set = cache_output_attribute_vector[idx];
+            assert(value_set);
+            
+            switch (value_set->type) {
+                case DataType::TYPE_BOOLEAN:
+                    output_attribute_dataset->addBoolValue(value_set->name, *value_set->getValuePtr<bool>());
+                    break;
+                case DataType::TYPE_INT32:
+                    output_attribute_dataset->addInt32Value(value_set->name, *value_set->getValuePtr<int32_t>());
+                    break;
+                case DataType::TYPE_INT64:
+                    output_attribute_dataset->addInt64Value(value_set->name, *value_set->getValuePtr<int64_t>());
+                    break;
+                case DataType::TYPE_DOUBLE:
+                    output_attribute_dataset->addDoubleValue(value_set->name, *value_set->getValuePtr<double>());
+                    break;
+                case DataType::TYPE_CLUSTER: {
+                    try {
+                        output_attribute_dataset->addCSDataValue(value_set->name, *value_set->getValuePtr<CDataWrapper>());
+                    } catch (...) {
+                        throw MetadataLoggingCException(getCUID(), -101, boost::str(boost::format("Invalid Json format for attribute '%1%' :'%2%") % value_set->name % value_set->getValuePtr<const char>()).c_str(), __PRETTY_FUNCTION__);
+                    }
+                    break;
+                }
+                case DataType::TYPE_STRING:
+                    //DEBUG_CODE(ACULAPP_ << value_set->name<<"-"<<value_set->getValuePtr<const char>();)
+                    output_attribute_dataset->addStringValue(value_set->name, value_set->getValuePtr<const char>());
+                    break;
+                case DataType::TYPE_BYTEARRAY:
+                    if (value_set->size) {
+                        if (value_set->sub_type.size() == 1) {
+                            output_attribute_dataset->addBinaryValue(value_set->name, value_set->sub_type[0], value_set->getValuePtr<char>(), value_set->size);
+                        } else {
+                            output_attribute_dataset->addBinaryValue(value_set->name, value_set->getValuePtr<char>(), value_set->size);
+                        }
+                    }
+                    break;
+                default:
+                    break;
+            }
+        }
+        //manage the burst information
+        manageBurstQueue();
+        //now we nede to push the outputdataset
+        push_dataset_size+=output_attribute_dataset->getBSONRawSize();
+        err = key_data_storage->pushDataSet(data_manager::KeyDataStorageDomainOutput, MOVE(output_attribute_dataset));
+        
+        //update counter
+        push_dataset_counter++;
+        
+        //reset chagned attribute into output dataset
+        if(!err){output_attribute_cache.resetChangedIndex();}
+        return err;
+    }
+    
+    //push system dataset
+    int AbstractControlUnit::pushInputDataset() {
+        int             err                   = 0;
+        AttributeCache& input_attribute_cache = attribute_value_shared_cache->getSharedDomain(DOMAIN_INPUT);
+        if (!input_attribute_cache.hasChanged()) return err;
+        //get the cdatawrapper for the pack
+        int64_t    cur_us                  = TimingUtil::getTimeStampInMicroseconds();
+        CDWShrdPtr input_attribute_dataset = key_data_storage->getNewDataPackForDomain(KeyDataStorageDomainInput);
+        if (input_attribute_dataset.get()) {
+            input_attribute_dataset->addInt64Value(ControlUnitDatapackCommonKey::RUN_ID, run_id);
+            //input dataset timestamp is added only when pushed on cache
+            input_attribute_dataset->addInt64Value(DataPackCommonKey::DPCK_TIMESTAMP, cur_us / 1000);
+            input_attribute_dataset->addInt64Value(DataPackCommonKey::DPCK_HIGH_RESOLUTION_TIMESTAMP, cur_us);
+            //fill the dataset
+            fillCDatawrapperWithCachedValue(cache_input_attribute_vector, *input_attribute_dataset);
+            
+            //push out the system dataset
+            err = key_data_storage->pushDataSet(data_manager::KeyDataStorageDomainInput, MOVE(input_attribute_dataset));
+            if(!err){input_attribute_cache.resetChangedIndex();}
+        } else {
+            ACULERR_ << " Cannot allocate packet.. err:"<<err;
+        }
+        return err;
+    }
+    
+    //push system dataset
+    int AbstractControlUnit::pushCustomDataset() {
+        int             err                    = 0;
+        AttributeCache& custom_attribute_cache = attribute_value_shared_cache->getSharedDomain(DOMAIN_CUSTOM);
+        if (!custom_attribute_cache.hasChanged()) return err;
+        //get the cdatawrapper for the pack
+        int64_t    cur_us                   = TimingUtil::getTimeStampInMicroseconds();
+        if(key_data_storage.get()){
+            CDWShrdPtr custom_attribute_dataset = key_data_storage->getNewDataPackForDomain(KeyDataStorageDomainCustom);
+            if (custom_attribute_dataset.get()) {
+                custom_attribute_dataset->addInt64Value(ControlUnitDatapackCommonKey::RUN_ID, run_id);
+                //input dataset timestamp is added only when pushed on cache
+                custom_attribute_dataset->addInt64Value(DataPackCommonKey::DPCK_TIMESTAMP, cur_us / 1000);
+                custom_attribute_dataset->addInt64Value(DataPackCommonKey::DPCK_HIGH_RESOLUTION_TIMESTAMP, cur_us);
+                
+                //fill the dataset
+                fillCDatawrapperWithCachedValue(cache_custom_attribute_vector, *custom_attribute_dataset);
+                
+                //push out the system dataset
+                err = key_data_storage->pushDataSet(data_manager::KeyDataStorageDomainCustom, MOVE(custom_attribute_dataset));
+                if(!err){custom_attribute_cache.resetChangedIndex();}
+            } else {
+                ACULERR_ << " Cannot allocate packet.. err:"<<err;
+            }
+        }
+        return err;
+    }
+    
+    int AbstractControlUnit::pushSystemDataset() {
+        int err = 0;
+        AttributeCache& system_attribute_cache = attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM);
+        if (!system_attribute_cache.hasChanged()) return err;
+        //get the cdatawrapper for the pack
+        int64_t    cur_us                   = TimingUtil::getTimeStampInMicroseconds();
+        CDWShrdPtr system_attribute_dataset = key_data_storage->getNewDataPackForDomain(KeyDataStorageDomainSystem);
+        if (system_attribute_dataset) {
+            system_attribute_dataset->addInt64Value(ControlUnitDatapackCommonKey::RUN_ID, run_id);
+            //input dataset timestamp is added only when pushed on cache
+            system_attribute_dataset->addInt64Value(DataPackCommonKey::DPCK_TIMESTAMP, cur_us / 1000);
+            system_attribute_dataset->addInt64Value(DataPackCommonKey::DPCK_HIGH_RESOLUTION_TIMESTAMP, cur_us);
+            //fill the dataset
+            fillCDatawrapperWithCachedValue(cache_system_attribute_vector, *system_attribute_dataset);
+            //ACULDBG_ << system_attribute_dataset->getJSONString();
+            //push out the system dataset
+            err = key_data_storage->pushDataSet(data_manager::KeyDataStorageDomainSystem, MOVE(system_attribute_dataset));
+            if(!err){system_attribute_cache.resetChangedIndex();}
+        }
+        return err;
+    }
+    
+    CDWShrdPtr AbstractControlUnit::writeCatalogOnCDataWrapper(AlarmCatalog& catalog,
+                                                               int32_t       dataset_type) {
+        CDWShrdPtr attribute_dataset = key_data_storage->getNewDataPackForDomain((KeyDataStorageDomain)dataset_type);
+        if (attribute_dataset) {
+            //fill datapack with
+            //! the dataaset can be pushed also in other moment
+            attribute_dataset->addInt64Value(DataPackCommonKey::DPCK_TIMESTAMP, TimingUtil::getTimeStamp());
+            attribute_dataset->addInt64Value(ControlUnitDatapackCommonKey::RUN_ID, run_id);
+            //scan all alarm ad create the datapack
+            size_t alarm_size = catalog.size();
+            for (unsigned int idx = 0;
+                 idx < alarm_size;
+                 idx++) {
+                AlarmDescription* alarm = catalog.getAlarmByOrderedID(idx);
+                attribute_dataset->addInt32Value(alarm->getAlarmName(),
+                                                 (uint32_t)alarm->getCurrentSeverityCode());
+            }
+        }
+        return attribute_dataset;
+    }
+    
+    int AbstractControlUnit::pushDevAlarmDataset() {
+        GET_CAT_OR_EXIT(StateVariableTypeAlarmDEV, 0);
+        int err = 0;
+        
+        CDWShrdPtr attribute_dataset = writeCatalogOnCDataWrapper(catalog,
+                                                                  DataPackCommonKey::DPCK_DATASET_TYPE_DEV_ALARM);
+        if (attribute_dataset) {
+            //push out the system dataset
+            err = key_data_storage->pushDataSet(KeyDataStorageDomainDevAlarm, MOVE(attribute_dataset));
+        }
+        return err;
+    }
+    
+    int AbstractControlUnit::pushCUAlarmDataset() {
+        GET_CAT_OR_EXIT(StateVariableTypeAlarmCU, 0);
+        int        err               = 0;
+        CDWShrdPtr attribute_dataset = writeCatalogOnCDataWrapper(catalog,
+                                                                  DataPackCommonKey::DPCK_DATASET_TYPE_CU_ALARM);
+        if (attribute_dataset) {
+            //push out the system dataset
+            err = key_data_storage->pushDataSet(KeyDataStorageDomainCUAlarm, MOVE(attribute_dataset));
+        }
+        return err;
+    }
+    
+    void AbstractControlUnit::manageBurstQueue() {
+        if (!current_burst.get()) {
+            DatasetBurstShrdPtr next_burst;
+            LQueueBurstReadLock wl = burst_queue.getReadLockObject();
+            if (!burst_queue().empty()) {
+                next_burst = burst_queue().front();
+                burst_queue().pop();
+            }
+            wl->unlock();
+            
+            if (next_burst.get()) {
+                switch (next_burst->type) {
+                    case chaos::ControlUnitNodeDefinitionType::DSStorageBurstTypeNPush:
+                        current_burst.reset(new PushStorageBurst(next_burst));
+                        break;
+                    case chaos::ControlUnitNodeDefinitionType::DSStorageBurstTypeMSec:
+                        current_burst.reset(new MSecStorageBurst(next_burst));
+                        break;
+                    default:
+                        break;
+                }
+                
+                //set the tag for burst
+                ACULDBG_ << "======= Start Burst tag:'" << current_burst->dataset_burst->tag << "' =======";
+                key_data_storage->addTag(current_burst->dataset_burst->tag);
+                key_data_storage->setTimingConfigurationBehaviour(false);
+                key_data_storage->setOverrideStorageType(DataServiceNodeDefinitionType::DSStorageTypeHistory);
+                *attribute_value_shared_cache->getAttributeValue(DOMAIN_SYSTEM, ControlUnitDatapackSystemKey::BURST_STATE)->getValuePtr<bool>() = true;
+                attribute_value_shared_cache->getAttributeValue(DOMAIN_SYSTEM, ControlUnitDatapackSystemKey::BURST_TAG)->setStringValue(current_burst->dataset_burst->tag, true, true);
+                attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM).markAllAsChanged();
+                pushSystemDataset();
+            }
+        } else {
+            if (!current_burst->active(timestamp_acq_cached_value->getValuePtr<int64_t>())) {
+                //remove the tag for the burst
+                ACULDBG_ << "======= End Burst tag:'" << current_burst->dataset_burst->tag << "' =======";
+                key_data_storage->removeTag(current_burst->dataset_burst->tag);
+                key_data_storage->setTimingConfigurationBehaviour(true);
+                key_data_storage->setOverrideStorageType(DataServiceNodeDefinitionType::DSStorageTypeUndefined);
+                *attribute_value_shared_cache->getAttributeValue(DOMAIN_SYSTEM, ControlUnitDatapackSystemKey::BURST_STATE)->getValuePtr<bool>() = false;
+                attribute_value_shared_cache->getAttributeValue(DOMAIN_SYSTEM, ControlUnitDatapackSystemKey::BURST_TAG)->setStringValue("");
+                attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM).markAllAsChanged();
+                //we need to remove it
+                current_burst.reset();
+                pushSystemDataset();
+            } else {
+                ACULDBG_ << "======= Active Burst tag:'" << current_burst->dataset_burst->tag << "' =======";
+            }
+        }
+    }
+    
+    void AbstractControlUnit::fillCDatawrapperWithCachedValue(std::vector<AttributeValue*>& cached_attributes, CDataWrapper& dataset) {
+        for (std::vector<AttributeValue*>::iterator it = cached_attributes.begin();
+             it != cached_attributes.end();
+             it++) {
+            (*it)->writeToCDataWrapper(dataset);
+        }
+    }
+    
+    //!timer for update push metric
+    void AbstractControlUnit::timeout() {
+        //update push metric
+        _updatePushRateMetric();
+    }
+    
+    bool AbstractControlUnit::isInputAttributeChangeAuthorizedByHandler(const std::string& attr_name) {
+        return dataset_attribute_manager.getHandlerResult(attr_name);
+    }
+    
+    void AbstractControlUnit::copyInitConfiguraiton(CDataWrapper& copy) {
+        if (init_configuration.get() == NULL) return;
+        
+        //copy all key
+        init_configuration->copyAllTo(copy);
+    }
+    
 #pragma mark Abstract Control Unit API
-void         AbstractControlUnit::addStateVariable(StateVariableType  variable_type,
+    void         AbstractControlUnit::addStateVariable(StateVariableType  variable_type,
+                                                       const std::string& state_variable_name,
+                                                       const std::string& state_variable_description) {
+        if (map_variable_catalog.count(variable_type) == 0) {
+            //add new catalog
+            map_variable_catalog.insert(MapStateVariablePair(variable_type, AlarmCatalog(stateVariableEnumToName(variable_type))));
+        }
+        AlarmCatalog& catalog = map_variable_catalog[variable_type];
+        catalog.addAlarm(new MultiSeverityAlarm(stateVariableEnumToName(variable_type),
+                                                state_variable_name,
+                                                state_variable_description));
+        //add this instance as
+        catalog.addAlarmHandler(state_variable_name,
+                                this);
+    }
+    
+    void AbstractControlUnit::setStateVariableSeverity(StateVariableType                            variable_type,
+                                                       const chaos::common::alarm::MultiSeverityAlarmLevel state_variable_severity) {
+        GET_CAT_OR_EXIT(variable_type, )
+        catalog.setAllAlarmSeverity(state_variable_severity);
+        
+        /*
+         AttributeCache& output_cache = attribute_value_shared_cache->getSharedDomain(DOMAIN_OUTPUT);
+         output_cache.getValueSettingByName(stateVariableEnumToName(variable_type))->setValue(CDataVariant(catalog.max()));
+         */
+        AttributeCache& output_cache = attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM);
+        output_cache.getValueSettingByName(stateVariableEnumToName(variable_type))->setValue(CDataVariant(catalog.maxLevel()));
+    }
+    
+    bool AbstractControlUnit::setStateVariableSeverity(StateVariableType             variable_type,
+                                                       const std::string&            state_variable_name,
+                                                       const MultiSeverityAlarmLevel state_variable_severity) {
+        GET_CAT_OR_EXIT(variable_type, false)
+        AlarmDescription* alarm = catalog.getAlarmByName(state_variable_name);
+        if (alarm == NULL) return false;
+        alarm->setCurrentSeverity(state_variable_severity);
+        //update global alarm output attribute
+        /*
+         AttributeCache& output_cache = attribute_value_shared_cache->getSharedDomain(DOMAIN_OUTPUT);
+         output_cache.getValueSettingByName(stateVariableEnumToName(variable_type))->setValue(CDataVariant(catalog.max()));
+         */
+        AttributeCache& output_cache = attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM);
+        output_cache.getValueSettingByName(stateVariableEnumToName(variable_type))->setValue(CDataVariant(catalog.maxLevel()));
+        
+        return true;
+    }
+    
+    bool AbstractControlUnit::setStateVariableSeverity(StateVariableType             variable_type,
+                                                       const unsigned int            state_variable_ordered_id,
+                                                       const MultiSeverityAlarmLevel state_variable_severity) {
+        GET_CAT_OR_EXIT(variable_type, false)
+        AlarmDescription* alarm = catalog.getAlarmByOrderedID(state_variable_ordered_id);
+        if (alarm == NULL) return false;
+        alarm->setCurrentSeverity(state_variable_severity);
+        //update global alarm output attribute
+        /*
+         AttributeCache& output_cache = attribute_value_shared_cache->getSharedDomain(DOMAIN_OUTPUT);
+         output_cache.getValueSettingByName(stateVariableEnumToName(variable_type))->setValue(CDataVariant(catalog.isCatalogClear()==false));
+         */
+        AttributeCache& output_cache = attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM);
+        output_cache.getValueSettingByName(stateVariableEnumToName(variable_type))->setValue(CDataVariant(catalog.isCatalogClear() == false));
+        
+        return true;
+    }
+    
+    bool AbstractControlUnit::getStateVariableSeverity(StateVariableType        variable_type,
+                                                       const std::string&       state_variable_name,
+                                                       MultiSeverityAlarmLevel& state_variable_severity) {
+        GET_CAT_OR_EXIT(variable_type, false)
+        AlarmDescription* alarm = catalog.getAlarmByName(state_variable_name);
+        if (alarm == NULL) return false;
+        state_variable_severity = static_cast<MultiSeverityAlarmLevel>(alarm->getCurrentSeverityCode());
+        return true;
+    }
+    
+    bool AbstractControlUnit::getStateVariableSeverity(StateVariableType        variable_type,
+                                                       const unsigned int       state_variable_ordered_id,
+                                                       MultiSeverityAlarmLevel& state_variable_severity) {
+        GET_CAT_OR_EXIT(variable_type, false)
+        AlarmDescription* alarm = catalog.getAlarmByOrderedID(state_variable_ordered_id);
+        if (alarm == NULL) return false;
+        state_variable_severity = static_cast<MultiSeverityAlarmLevel>(alarm->getCurrentSeverityCode());
+        return true;
+    }
+    
+    void AbstractControlUnit::alarmChanged(const std::string& state_variable_tag,
                                            const std::string& state_variable_name,
-                                           const std::string& state_variable_description) {
-  if (map_variable_catalog.count(variable_type) == 0) {
-    //add new catalog
-    map_variable_catalog.insert(MapStateVariablePair(variable_type, AlarmCatalog(stateVariableEnumToName(variable_type))));
-  }
-  AlarmCatalog& catalog = map_variable_catalog[variable_type];
-  catalog.addAlarm(new MultiSeverityAlarm(stateVariableEnumToName(variable_type),
-                                          state_variable_name,
-                                          state_variable_description));
-  //add this instance as
-  catalog.addAlarmHandler(state_variable_name,
-                          this);
-}
-
-void AbstractControlUnit::setStateVariableSeverity(StateVariableType                            variable_type,
-                                                   const chaos::common::alarm::MultiSeverityAlarmLevel state_variable_severity) {
-  GET_CAT_OR_EXIT(variable_type, )
-  catalog.setAllAlarmSeverity(state_variable_severity);
-
-  /*
-    AttributeCache& output_cache = attribute_value_shared_cache->getSharedDomain(DOMAIN_OUTPUT);
-    output_cache.getValueSettingByName(stateVariableEnumToName(variable_type))->setValue(CDataVariant(catalog.max()));
-    */
-  AttributeCache& output_cache = attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM);
-  output_cache.getValueSettingByName(stateVariableEnumToName(variable_type))->setValue(CDataVariant(catalog.maxLevel()));
-}
-
-bool AbstractControlUnit::setStateVariableSeverity(StateVariableType             variable_type,
-                                                   const std::string&            state_variable_name,
-                                                   const MultiSeverityAlarmLevel state_variable_severity) {
-  GET_CAT_OR_EXIT(variable_type, false)
-  AlarmDescription* alarm = catalog.getAlarmByName(state_variable_name);
-  if (alarm == NULL) return false;
-  alarm->setCurrentSeverity(state_variable_severity);
-  //update global alarm output attribute
-  /*
-    AttributeCache& output_cache = attribute_value_shared_cache->getSharedDomain(DOMAIN_OUTPUT);
-    output_cache.getValueSettingByName(stateVariableEnumToName(variable_type))->setValue(CDataVariant(catalog.max()));
-   */
-  AttributeCache& output_cache = attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM);
-  output_cache.getValueSettingByName(stateVariableEnumToName(variable_type))->setValue(CDataVariant(catalog.maxLevel()));
-
-  return true;
-}
-
-bool AbstractControlUnit::setStateVariableSeverity(StateVariableType             variable_type,
-                                                   const unsigned int            state_variable_ordered_id,
-                                                   const MultiSeverityAlarmLevel state_variable_severity) {
-  GET_CAT_OR_EXIT(variable_type, false)
-  AlarmDescription* alarm = catalog.getAlarmByOrderedID(state_variable_ordered_id);
-  if (alarm == NULL) return false;
-  alarm->setCurrentSeverity(state_variable_severity);
-  //update global alarm output attribute
-  /*
-    AttributeCache& output_cache = attribute_value_shared_cache->getSharedDomain(DOMAIN_OUTPUT);
-    output_cache.getValueSettingByName(stateVariableEnumToName(variable_type))->setValue(CDataVariant(catalog.isCatalogClear()==false));
-   */
-  AttributeCache& output_cache = attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM);
-  output_cache.getValueSettingByName(stateVariableEnumToName(variable_type))->setValue(CDataVariant(catalog.isCatalogClear() == false));
-
-  return true;
-}
-
-bool AbstractControlUnit::getStateVariableSeverity(StateVariableType        variable_type,
-                                                   const std::string&       state_variable_name,
-                                                   MultiSeverityAlarmLevel& state_variable_severity) {
-  GET_CAT_OR_EXIT(variable_type, false)
-  AlarmDescription* alarm = catalog.getAlarmByName(state_variable_name);
-  if (alarm == NULL) return false;
-  state_variable_severity = static_cast<MultiSeverityAlarmLevel>(alarm->getCurrentSeverityCode());
-  return true;
-}
-
-bool AbstractControlUnit::getStateVariableSeverity(StateVariableType        variable_type,
-                                                   const unsigned int       state_variable_ordered_id,
-                                                   MultiSeverityAlarmLevel& state_variable_severity) {
-  GET_CAT_OR_EXIT(variable_type, false)
-  AlarmDescription* alarm = catalog.getAlarmByOrderedID(state_variable_ordered_id);
-  if (alarm == NULL) return false;
-  state_variable_severity = static_cast<MultiSeverityAlarmLevel>(alarm->getCurrentSeverityCode());
-  return true;
-}
-
-void AbstractControlUnit::alarmChanged(const std::string& state_variable_tag,
-                                       const std::string& state_variable_name,
-                                       const int8_t       state_variable_severity) {
-  int variable_type = stateVariableNameToEnum(state_variable_tag);
-  if (variable_type == -1) return;
-
-  GET_CAT_OR_EXIT((StateVariableType)variable_type, )
-  AlarmDescription* alarm = catalog.getAlarmByName(state_variable_name);
-  CHAOS_ASSERT(alarm);
-
-  //update alarm log
-  alarm_logging_channel->logAlarm(getCUID(),
-                                  "AbstractControlUnit",
-                                  *alarm);
-
-  switch ((StateVariableType)variable_type) {
-    case StateVariableTypeAlarmCU:
-      //update dataset alarm on cds
-      pushCUAlarmDataset();
-      break;
-
-    case StateVariableTypeAlarmDEV:
-      //update dataset alarm on cds
-      pushDevAlarmDataset();
-      break;
-  }
-  AttributeCache& output_cache = attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM);
-  output_cache.getValueSettingByName(stateVariableEnumToName((StateVariableType)variable_type))->setValue(CDataVariant(catalog.maxLevel()));
-
-  attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM).markAllAsChanged();
-  pushSystemDataset();
-}
-
-void AbstractControlUnit::setBusyFlag(bool state) {
-  AttributeCache& system_cache = attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM);
-  if (system_cache.hasName("busy")) {
-    system_cache.getValueSettingByName("busy")->setValue(CDataVariant(state));
-  }
-}
-
-const bool AbstractControlUnit::getBusyFlag() const {
-  AttributeCache& system_cache = attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM);
-  if (system_cache.hasName("busy")) {
-    return system_cache.getValueSettingByName("busy")->getAsVariant().asBool();
-  } else {
-    return false;
-  }
-}
-
-void AbstractControlUnit::metadataLogging(const std::string&                                                      subject,
-                                          const chaos::common::metadata_logging::StandardLoggingChannel::LogLevel log_level,
-                                          const std::string&                                                      message) {
-  if (standard_logging_channel == NULL) return;
-
-  standard_logging_channel->logMessage(getCUID(),
-                                       subject,
-                                       log_level,
-                                       message);
-  switch (log_level) {
-    case StandardLoggingChannel::LogLevelInfo:
-      ACULAPP_ << log_level;
-      break;
-    case StandardLoggingChannel::LogLevelDebug:
-      ACULDBG_ << log_level;
-      break;
-    case StandardLoggingChannel::LogLevelWarning:
-      ACULWRN_ << log_level;
-      break;
-    case StandardLoggingChannel::LogLevelError:
-      ACULERR_ << log_level;
-      break;
-    case StandardLoggingChannel::LogLevelFatal:
-      ACULNOTE_ << log_level;
-      break;
-  }
-}
-
-void AbstractControlUnit::metadataLogging(const StandardLoggingChannel::LogLevel log_level,
-                                          const std::string&                     message) {
-  metadataLogging("AbstractControlUnit",
-                  log_level,
-                  message);
-}
+                                           const int8_t       state_variable_severity) {
+        int variable_type = stateVariableNameToEnum(state_variable_tag);
+        if (variable_type == -1) return;
+        
+        GET_CAT_OR_EXIT((StateVariableType)variable_type, )
+        AlarmDescription* alarm = catalog.getAlarmByName(state_variable_name);
+        CHAOS_ASSERT(alarm);
+        
+        //update alarm log
+        alarm_logging_channel->logAlarm(getCUID(),
+                                        "AbstractControlUnit",
+                                        *alarm);
+        
+        switch ((StateVariableType)variable_type) {
+            case StateVariableTypeAlarmCU:
+                //update dataset alarm on cds
+                pushCUAlarmDataset();
+                break;
+                
+            case StateVariableTypeAlarmDEV:
+                //update dataset alarm on cds
+                pushDevAlarmDataset();
+                break;
+        }
+        AttributeCache& output_cache = attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM);
+        output_cache.getValueSettingByName(stateVariableEnumToName((StateVariableType)variable_type))->setValue(CDataVariant(catalog.maxLevel()));
+        
+        attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM).markAllAsChanged();
+        pushSystemDataset();
+    }
+    
+    void AbstractControlUnit::setBusyFlag(bool state) {
+        AttributeCache& system_cache = attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM);
+        if (system_cache.hasName("busy")) {
+            system_cache.getValueSettingByName("busy")->setValue(CDataVariant(state));
+        }
+    }
+    
+    const bool AbstractControlUnit::getBusyFlag() const {
+        AttributeCache& system_cache = attribute_value_shared_cache->getSharedDomain(DOMAIN_SYSTEM);
+        if (system_cache.hasName("busy")) {
+            return system_cache.getValueSettingByName("busy")->getAsVariant().asBool();
+        } else {
+            return false;
+        }
+    }
+    
+    void AbstractControlUnit::metadataLogging(const std::string&                                                      subject,
+                                              const chaos::common::metadata_logging::StandardLoggingChannel::LogLevel log_level,
+                                              const std::string&                                                      message) {
+        if (standard_logging_channel == NULL) return;
+        
+        standard_logging_channel->logMessage(getCUID(),
+                                             subject,
+                                             log_level,
+                                             message);
+        switch (log_level) {
+            case StandardLoggingChannel::LogLevelInfo:
+                ACULAPP_ << log_level;
+                break;
+            case StandardLoggingChannel::LogLevelDebug:
+                ACULDBG_ << log_level;
+                break;
+            case StandardLoggingChannel::LogLevelWarning:
+                ACULWRN_ << log_level;
+                break;
+            case StandardLoggingChannel::LogLevelError:
+                ACULERR_ << log_level;
+                break;
+            case StandardLoggingChannel::LogLevelFatal:
+                ACULNOTE_ << log_level;
+                break;
+        }
+    }
+    
+    void AbstractControlUnit::metadataLogging(const StandardLoggingChannel::LogLevel log_level,
+                                              const std::string&                     message) {
+        metadataLogging("AbstractControlUnit",
+                        log_level,
+                        message);
+    }