diff --git a/ChaosAgent/AgentRegister.cpp b/ChaosAgent/AgentRegister.cpp
index 2e5c3a9f129a3fc0811a0afbccb2e12676dd7784..47e6b30fcbf8d4b4b6cbca89cb9bc3eb51dcd4eb 100644
--- a/ChaosAgent/AgentRegister.cpp
+++ b/ChaosAgent/AgentRegister.cpp
@@ -134,6 +134,7 @@ CDWUniquePtr AgentRegister::registrationACK(CDWUniquePtr  ack_pack) {
                 if(ack_pack->hasKey("agent_description") &&
                    ack_pack->isCDataWrapperValue("agent_description")) {
                     ChaosUniquePtr<chaos::common::data::CDataWrapper> aget_desc_ser(ack_pack->getCSDataValue("agent_description"));
+                    DBG<<"AGENT DESC:"<<aget_desc_ser->getJSONString();
                     agent_instance_sd_wrapper.deserialize(aget_desc_ser.get());
                 }
                 break;
@@ -151,12 +152,15 @@ CDWUniquePtr AgentRegister::registrationACK(CDWUniquePtr  ack_pack) {
 ChaosUniquePtr<chaos::common::data::CDataWrapper> AgentRegister::getAgentRegistrationPack() {
     ChaosUniquePtr<chaos::common::data::CDataWrapper> result(new CDataWrapper());
     if(result.get() == NULL) return result;
+    std::string hostport;
+     NetworkBroker::getInstance()->getPublishedHostAndPort(hostport);
     result->addStringValue(NodeDefinitionKey::NODE_UNIQUE_ID,
                            ChaosAgent::getInstance()->settings.agent_uid);
     result->addStringValue(chaos::NodeDefinitionKey::NODE_TYPE,
                            chaos::NodeType::NODE_TYPE_AGENT);
     result->addStringValue(NodeDefinitionKey::NODE_RPC_ADDR,
-                           chaos::GlobalConfiguration::getInstance()->getLocalServerAddressAnBasePort());
+                            hostport
+                           /*chaos::GlobalConfiguration::getInstance()->getLocalServerAddressAnBasePort()*/);
     result->addStringValue(NodeDefinitionKey::NODE_HOST_NAME,
                            chaos::GlobalConfiguration::getInstance()->getHostname());
     if(chaos::GlobalConfiguration::getInstance()->getDesc()!=""){
@@ -246,9 +250,11 @@ void AgentRegister::timeout() {
                     end = agent_instance_sd_wrapper().node_associated.end();
                     it != end;
                     it++) {
+                        DBG<<"Association:"<<it->associated_node_uid;
                        chaos::common::data::CDWUniquePtr param=ChaosAgent::getInstance()->checkAndPrepareScript(*it);
+
                     ///
-                    if(param.get()&&it->auto_start) {
+                    if(it->auto_start) {
                         INFO << CHAOS_FORMAT("Autostart node %1%", %it->associated_node_uid);
                         LAUNCH_PROCESS(*it,param);
                         if(it->keep_alive) {
diff --git a/ChaosAgent/ChaosAgent.cpp b/ChaosAgent/ChaosAgent.cpp
index 64c8e64851604f6703b1f5281edcaefd81968ba4..8f92f408fbba10f7b7568df24fc8d3f399b0dac2 100644
--- a/ChaosAgent/ChaosAgent.cpp
+++ b/ChaosAgent/ChaosAgent.cpp
@@ -23,7 +23,7 @@
 #include "chaos_agent_constants.h"
 #include <chaos/common/utility/FSUtility.h>
 #include <chaos/common/metadata_logging/metadata_logging.h>
-
+//#include <chaos_service_common/health_system/HealtManagerDirect.h>
 #include <chaos/common/healt_system/HealtManager.h>
 #include <chaos/common/io/SharedManagedDirecIoDataDriver.h>
 #include <chaos/common/configuration/GlobalConfiguration.h>
@@ -74,13 +74,15 @@ void ChaosAgent::init(void *init_data)  {
         settings.working_directory = FSUtility::getExecutablePath();
     }
     
-    
+    ChaosAgent::getInstance()->settings.agent_uid=nodeuid;
     //settings.agent_uid = CHAOS_FORMAT("ChaosAgent_%1%",%chaos::GlobalConfiguration::getInstance()->getLocalServerAddressAnBasePort());
     
     InizializableService::initImplementation(SharedManagedDirecIoDataDriver::getInstance(), NULL, "SharedManagedDirecIoDataDriver", __PRETTY_FUNCTION__);
     InizializableService::initImplementation(chaos::common::metadata_logging::MetadataLoggingManager::getInstance(), NULL, "MetadataLoggingManager", __PRETTY_FUNCTION__);
 
     StartableService::initImplementation(HealtManager::getInstance(), NULL, "HealthManager", __PRETTY_FUNCTION__);
+   // StartableService::initImplementation(HealtManagerDirect::getInstance(), NULL, "HealtManagerDirect", __PRETTY_FUNCTION__);
+
     agent_register.reset(new AgentRegister(), "AgentRegister");
     CHECK_ASSERTION_THROW_AND_LOG((agent_register.get() != NULL), ERROR, -1, "AgentRegister instantiation failed");
     agent_register.init(NULL, __PRETTY_FUNCTION__);
@@ -96,7 +98,7 @@ void ChaosAgent::init(void *init_data)  {
     }
 
     
-    std::string script_path=getGlobalConfigurationInstance()->getOption< std::string >(OPT_SCRIPT_DIR) +"/"+ ChaosAgent::getInstance()->settings.agent_uid;
+    std::string script_path=getGlobalConfigurationInstance()->getOption< std::string >(OPT_SCRIPT_DIR) +"/"+ nodeuid;
     boost::filesystem::path p(script_path);
     ChaosAgent::getInstance()->settings.script_dir=script_path;
     ChaosAgent::getInstance()->settings.restport=restport;
@@ -112,7 +114,7 @@ void ChaosAgent::init(void *init_data)  {
         } catch(boost::filesystem::filesystem_error& e){
             std::stringstream ss;
             ss<< " Exception creating directory:"<<p<<" error:"<< e.what();
-            logError(ChaosAgent::getInstance()->settings.agent_uid,ss.str(),__PRETTY_FUNCTION__);
+            logError(nodeuid,ss.str(),__PRETTY_FUNCTION__);
             
             ERROR<<ss.str();
       }
@@ -126,10 +128,6 @@ void ChaosAgent::start() {
     StartableService::startImplementation(HealtManager::getInstance(), "HealthManager", __PRETTY_FUNCTION__);
     ChaosCommon<ChaosAgent>::start();
     agent_register.start(__PRETTY_FUNCTION__);
-#ifndef OLD_PROCESS_MANAGEMENT
-
-    procRestUtil->start(true); // start in background
-#endif
 
  if (signal((int) SIGINT, ChaosAgent::signalHanlder) == SIG_ERR) {
         throw CException(-1, "Error registering SIGINT signal", __PRETTY_FUNCTION__);
@@ -142,6 +140,14 @@ void ChaosAgent::start() {
     if (signal((int) SIGTERM, ChaosAgent::signalHanlder) == SIG_ERR) {
         throw CException(-3, "Error registering SIGTERM signal", __PRETTY_FUNCTION__);
     }
+
+#ifndef OLD_PROCESS_MANAGEMENT
+    DBG << " STARTING REST SERVER ON PORT:" << ChaosAgent::getInstance()->settings.restport;
+
+    sleep(chaos::common::constants::HBTimersTimeoutinMSec/1000);
+    procRestUtil->start(true); // start in background
+#endif
+
     wait_close_semaphore.waitRaw();
     
     #ifndef OLD_PROCESS_MANAGEMENT
@@ -210,7 +216,7 @@ std::string ChaosAgent::scriptWorkingDir(std::string scriptname,std::string uid)
             (boost::filesystem::create_directories(working_dir) == false)) {
             std::stringstream ss;
             ss<<"cannot create directory:\""<<working_dir<<"\"";
-            logError(ChaosAgent::getInstance()->settings.agent_uid,ss.str(),__PRETTY_FUNCTION__);
+            logError(nodeuid,ss.str(),__PRETTY_FUNCTION__);
 
          ERROR<<ss.str();
          return std::string();
@@ -218,13 +224,13 @@ std::string ChaosAgent::scriptWorkingDir(std::string scriptname,std::string uid)
   } catch(boost::filesystem::filesystem_error& e){
             std::stringstream ss;
             ss<< " Filesystem Exception creating directory:"<<working_dir<<" error:"<< e.what();
-            logError(ChaosAgent::getInstance()->settings.agent_uid,ss.str(),__PRETTY_FUNCTION__);
+            logError(nodeuid,ss.str(),__PRETTY_FUNCTION__);
 
     } catch(...){
         std::stringstream ss;
 
          ss<<"Exception cannot create directory:\""<<working_dir<<"\"";
-        logError(ChaosAgent::getInstance()->settings.agent_uid,ss.str(),__PRETTY_FUNCTION__);
+        logError(nodeuid,ss.str(),__PRETTY_FUNCTION__);
 
         ERROR<<ss.str();
                                                     
@@ -251,7 +257,7 @@ std::string ChaosAgent::scriptWorkingDir(std::string scriptname,std::string uid)
   } else {
       std::stringstream ss;
       ss<<"cannot write file \""<<fname<<"\" of "<<towrite->getBufferSize()<<" bytes, error:"<< strerror(errno);
-    logError(ChaosAgent::getInstance()->settings.agent_uid,ss.str(),__PRETTY_FUNCTION__);
+    logError(nodeuid,ss.str(),__PRETTY_FUNCTION__);
 
 //throw CException(-10, ss.str(), __PRETTY_FUNCTION__);
 
diff --git a/ChaosAgent/chaos_agent_constants.h b/ChaosAgent/chaos_agent_constants.h
index cb7cec0ffc7c6ec230a1b7afe0ba6eaff822a591..80a268f83a9296f809b3f2183a3c2831a8d3e6d3 100644
--- a/ChaosAgent/chaos_agent_constants.h
+++ b/ChaosAgent/chaos_agent_constants.h
@@ -24,7 +24,6 @@
 
 namespace chaos {
     namespace agent {
-#define OPT_NODE_UID             "node-uid"
 
 #define OPT_WORKING_DIR             "working-dir"
 #define OPT_ENABLE_SEPARATE_US_LOG  "enable-separate-us-logging"
diff --git a/ChaosAgent/main.cpp b/ChaosAgent/main.cpp
index dfbd91c63d01f2da67461cd044261a427e91348f..8f7b6664f20436d542ea51e34e8ee2fbd92166f3 100644
--- a/ChaosAgent/main.cpp
+++ b/ChaosAgent/main.cpp
@@ -51,10 +51,6 @@ int main(int argc, const char * argv[]) {
                                                                                               "/tmp/script_dir",
                                                                                               &ChaosAgent::getInstance()->settings.script_dir);
         //data worker
-        ChaosAgent::getInstance()->getGlobalConfigurationInstance()->addOption< std::string >(OPT_NODE_UID,
-                                                                                              "Node Unique Name",
-                                                                                              ChaosAgent::getInstance()->settings.agent_uid,
-                                                                                              &ChaosAgent::getInstance()->settings.agent_uid);
          ChaosAgent::getInstance()->getGlobalConfigurationInstance()->addOption< std::string >(OPT_WORKING_DIR,
                                                                                               "Working directory for agent",
                                                                                               "",
diff --git a/ChaosAgent/utility/ProcRestUtil.cpp b/ChaosAgent/utility/ProcRestUtil.cpp
index 809782dd9ebf5a840aa33b14208dd590a962d33a..57b8ae72abf9f35131d267bd7556cf72e65f1efd 100644
--- a/ChaosAgent/utility/ProcRestUtil.cpp
+++ b/ChaosAgent/utility/ProcRestUtil.cpp
@@ -95,7 +95,7 @@ void ProcRestUtil::launchProcess(const chaos::service_common::data::agent::Agent
             //init_file_stream << CHAOS_FORMAT("%1%=",%InitOption::OPT_LOG_ON_MDS) << std::endl;
        // }
         
-        init_file_stream << CHAOS_FORMAT("unit-server-alias=%1%",%node_association_info.associated_node_uid) << std::endl;
+        init_file_stream << CHAOS_FORMAT( "%1%=%2%",%std::string(InitOption::OPT_NODEUID)%node_association_info.associated_node_uid) << std::endl;
         
         //append metadata server from agent configuration
         VectorNetworkAddress mds_vec = GlobalConfiguration::getInstance()->getMetadataServerAddressList();
@@ -105,6 +105,36 @@ void ProcRestUtil::launchProcess(const chaos::service_common::data::agent::Agent
             mds_it++) {
             init_file_stream << CHAOS_FORMAT("metadata-server=%1%",%mds_it->ip_port) << std::endl;
         }
+chaos::common::data::CDataWrapper* conf=GlobalConfiguration::getInstance()->getConfiguration();
+
+        if(conf->hasKey(InitOption::OPT_MSG_BROKER_SERVER)){
+            init_file_stream <<CHAOS_FORMAT("%1%=%2%",%std::string(InitOption::OPT_MSG_BROKER_SERVER)%conf->getStringValue(InitOption::OPT_MSG_BROKER_SERVER)) << std::endl;
+        }
+
+        if(conf->hasKey(InitOption::OPT_MSG_BROKER_DRIVER)){
+            init_file_stream <<CHAOS_FORMAT("%1%=%2%",%std::string(InitOption::OPT_MSG_BROKER_DRIVER)%conf->getStringValue(InitOption::OPT_MSG_BROKER_DRIVER)) << std::endl;
+        }
+        std::vector<std::string> prod_opt,cons_opt;
+        if(conf->hasKey(InitOption::OPT_MSG_PRODUCER_KVP)){
+            chaos::common::data::CMultiTypeDataArrayWrapperSPtr r=conf->getVectorValue(InitOption::OPT_MSG_PRODUCER_KVP);
+            if(r.get()){
+                prod_opt=*r;
+            }
+        }
+        for(std::vector<std::string>::iterator it = prod_opt.begin();it != prod_opt.end();
+            it++) {
+            init_file_stream <<CHAOS_FORMAT("%1%=%2%",%std::string(InitOption::OPT_MSG_PRODUCER_KVP)%*it) << std::endl;
+        }
+        if(conf->hasKey(InitOption::OPT_MSG_CONSUMER_KVP)){
+            chaos::common::data::CMultiTypeDataArrayWrapperSPtr r=conf->getVectorValue(InitOption::OPT_MSG_CONSUMER_KVP);
+            if(r.get()){
+                cons_opt=*r;
+            }
+        }
+        for(std::vector<std::string>::iterator it = cons_opt.begin();it != cons_opt.end();
+            it++) {
+            init_file_stream <<CHAOS_FORMAT("%1%=%2%",%std::string(InitOption::OPT_MSG_CONSUMER_KVP)%*it) << std::endl;
+        }
 
         //append user defined paramenter
         init_file_stream.write(node_association_info.configuration_file_content.c_str(), node_association_info.configuration_file_content.length());
diff --git a/ChaosAgent/utility/ProcUtil.cpp b/ChaosAgent/utility/ProcUtil.cpp
index 99bdc82992281035a1f7c86058553296a2fc00c6..1172e87b66f2d27f9a00d005ddae74795478580b 100644
--- a/ChaosAgent/utility/ProcUtil.cpp
+++ b/ChaosAgent/utility/ProcUtil.cpp
@@ -222,7 +222,7 @@ void ProcUtil::launchProcess(const chaos::service_common::data::agent::AgentAsso
             init_file_stream << CHAOS_FORMAT("%1%=",%InitOption::OPT_LOG_ON_MDS) << std::endl;
         }
         
-        init_file_stream << CHAOS_FORMAT("unit-server-alias=%1%",%node_association_info.associated_node_uid) << std::endl;
+        init_file_stream << CHAOS_FORMAT("%1%=%2%",%std::string(OPT_NODEUID)%node_association_info.associated_node_uid) << std::endl;
         
         //append metadata server from agent configuration
         VectorNetworkAddress mds_vec = GlobalConfiguration::getInstance()->getMetadataServerAddressList();
@@ -232,7 +232,36 @@ void ProcUtil::launchProcess(const chaos::service_common::data::agent::AgentAsso
             mds_it++) {
             init_file_stream << CHAOS_FORMAT("metadata-server=%1%",%mds_it->ip_port) << std::endl;
         }
-        
+        chaos::common::data::CDataWrapper* conf=GlobalConfiguration::getInstance()->getConfiguration();
+
+        if(conf->hasKey(std::string,InitOption::OPT_MSG_BROKER_SERVER)){
+            init_file_stream <<CHAOS_FORMAT("%1%=%2%",std::string(InitOption::OPT_MSG_BROKER_SERVER)%conf->getStringValue(InitOption::OPT_MSG_BROKER_SERVER)) << std::endl;
+        }
+
+        if(conf->hasKey(std::string,InitOption::OPT_MSG_BROKER_DRIVER)){
+            init_file_stream <<CHAOS_FORMAT("%1%=%2%",std::string(InitOption::OPT_MSG_BROKER_DRIVER)%conf->getStringValue(InitOption::OPT_MSG_BROKER_DRIVER)) << std::endl;
+        }
+        std::vector<std::string> prod_opt,cons_opt;
+        if(conf->hasKey(InitOption::OPT_MSG_PRODUCER_KVP)){
+            chaos::common::data::CMultiTypeDataArrayWrapperSPtr r=conf->getVectorValue(InitOption::OPT_MSG_PRODUCER_KVP);
+            if(r.get()){
+                prod_opt=*r;
+            }
+        }
+        for(std::vector<std::string> it = prod_opt.begin();it != prod_opt.end();
+            it++) {
+            init_file_stream <<CHAOS_FORMAT("%1%=%2%",std::string(InitOption::OPT_MSG_PRODUCER_KVP)%*it) << std::endl;
+        }
+        if(conf->hasKey(InitOption::OPT_MSG_CONSUMER_KVP)){
+            chaos::common::data::CMultiTypeDataArrayWrapperSPtr r=conf->getVectorValue(InitOption::OPT_MSG_CONSUMER_KVP);
+            if(r.get()){
+                cons_opt=*r;
+            }
+        }
+        for(std::vector<std::string> it = cons_opt.begin();it != cons_opt.end();
+            it++) {
+            init_file_stream <<CHAOS_FORMAT("%1%=%2%",std::string(InitOption::OPT_MSG_CONSUMER_KVP)%*it) << std::endl;
+        }
         //append user defined paramenter
         init_file_stream.write(node_association_info.configuration_file_content.c_str(), node_association_info.configuration_file_content.length());
         init_file_stream.close();
diff --git a/ChaosMetadataService/ChaosMetadataService.cpp b/ChaosMetadataService/ChaosMetadataService.cpp
index e5eb277f9aec3e4a1cab2a82d3ba02f69cfac9f2..df82afea1f5cf7ebb4d5b120792163d87c42424c 100644
--- a/ChaosMetadataService/ChaosMetadataService.cpp
+++ b/ChaosMetadataService/ChaosMetadataService.cpp
@@ -19,24 +19,24 @@
  * permissions and limitations under the Licence.
  */
 
-#include "mds_constants.h"
 #include "ChaosMetadataService.h"
 #include <chaos_service_common/DriverPoolManager.h>
 #include <chaos_service_common/health_system/HealtManagerDirect.h>
+#include "mds_constants.h"
 
 #include "QueryDataConsumer.h"
 #include "QueryDataMsgPSConsumer.h"
 
 #include "object_storage/object_storage.h"
 
-#include <csignal>
+#include <chaos/common/configuration/GlobalConfiguration.h>
 #include <chaos/common/exception/CException.h>
-#include <boost/format.hpp>
-#include <boost/algorithm/string.hpp>
 #include <chaos/common/io/SharedManagedDirecIoDataDriver.h>
-#include <regex>
 #include <chaos/common/utility/ObjectFactoryRegister.h>
-#include <chaos/common/configuration/GlobalConfiguration.h>
+#include <boost/algorithm/string.hpp>
+#include <boost/format.hpp>
+#include <csignal>
+#include <regex>
 using namespace std;
 using namespace chaos;
 using namespace chaos::common::io;
@@ -56,479 +56,532 @@ using namespace chaos::common::cache_system;
 using namespace chaos::service_common::persistence::data_access;
 
 WaitSemaphore ChaosMetadataService::waitCloseSemaphore;
-uint64_t ChaosMetadataService::timePrecisionMask=0xFFFFFFFFFFFFFFF0ULL;
-
-#define LCND_LAPP   INFO_LOG(ChaosMetadataService)
-#define LCND_LDBG   DBG_LOG(ChaosMetadataService)
-#define LCND_LERR   ERR_LOG(ChaosMetadataService)
-#define log(x) LCND_LDBG<<x
-ChaosMetadataService::ChaosMetadataService(){ingore_unreg_po = true;
+uint64_t      ChaosMetadataService::timePrecisionMask = 0xFFFFFFFFFFFFFFF0ULL;
+
+#define LCND_LAPP INFO_LOG(ChaosMetadataService)
+#define LCND_LDBG DBG_LOG(ChaosMetadataService)
+#define LCND_LERR ERR_LOG(ChaosMetadataService)
+#define log(x) LCND_LDBG << x
+ChaosMetadataService::ChaosMetadataService() {
+  ingore_unreg_po = true;
+  is_present      = false;
 };
-ChaosMetadataService::~ChaosMetadataService(){}
+ChaosMetadataService::~ChaosMetadataService() {}
 
 //! C and C++ attribute parser
 /*!
  Specialized option for startup c and cpp program main options parameter
  */
-void ChaosMetadataService::init(int argc, const char* argv[])  {
-    ChaosCommon<ChaosMetadataService>::init(argc, argv);
+void ChaosMetadataService::init(int argc, const char* argv[]) {
+  is_present = false;
+  ChaosCommon<ChaosMetadataService>::init(argc, argv);
+
+  
 }
-//!stringbuffer parser
+//! stringbuffer parser
 /*
  specialized option for string stream buffer with boost semantics
  */
-void ChaosMetadataService::init(istringstream &initStringStream)  {
-    ChaosCommon<ChaosMetadataService>::init(initStringStream);
+void ChaosMetadataService::init(istringstream& initStringStream) {
+  is_present = false;
+  ChaosCommon<ChaosMetadataService>::init(initStringStream);
 }
 
 /*
  *
  */
-void ChaosMetadataService::init(void *init_data)  {
-    try {
-        ChaosCommon<ChaosMetadataService>::init(init_data);
-        
-        if (signal((int) SIGINT, ChaosMetadataService::signalHanlder) == SIG_ERR) {
-            throw CException(-1, "Error registering SIGINT signal", __PRETTY_FUNCTION__);
-        }
-        
-        if (signal((int) SIGQUIT, ChaosMetadataService::signalHanlder) == SIG_ERR) {
-            throw CException(-2, "Error registering SIG_ERR signal", __PRETTY_FUNCTION__);
-        }
-        
-        if (signal((int) SIGTERM, ChaosMetadataService::signalHanlder) == SIG_ERR) {
-            throw CException(-3, "Error registering SIGTERM signal", __PRETTY_FUNCTION__);
-        }
-        
-        //scan the setting
-        if(!setting.persistence_implementation.size()) {
-            //no cache server provided
-            throw chaos::CException(-3, "No persistence implementation provided", __PRETTY_FUNCTION__);
-        }
-        
-        if(!setting.persistence_server_list.size()) {
-            //no cache server provided
-            throw chaos::CException(-4, "No persistence's server list provided", __PRETTY_FUNCTION__);
-        }
-        
-        if(getGlobalConfigurationInstance()->hasOption(chaos::service_common::persistence::OPT_PERSITENCE_KV_PARAMTER)) {
-            fillKVParameter(setting.persistence_kv_param_map,
-                            getGlobalConfigurationInstance()->getOption< std::vector< std::string> >(chaos::service_common::persistence::OPT_PERSITENCE_KV_PARAMTER));
-        }
-        
-        //check for mandatory configuration
-        if(!getGlobalConfigurationInstance()->hasOption(OPT_CACHE_SERVER_LIST)) {
-            //no cache server provided
-            throw chaos::CException(-3, "No cache server provided", __PRETTY_FUNCTION__);
-        }
-        
-        if(getGlobalConfigurationInstance()->hasOption(OPT_SYNCTIME_ERROR)) {
-           timeError_opt= getGlobalConfigurationInstance()->getOption< uint32_t >(OPT_SYNCTIME_ERROR);
-
-        }
-
-        if(timeError_opt>2048){
-            std::stringstream ss;
-            ss<<"Specified time synchronization error to high:"<<timeError_opt<<" ms";
-            throw chaos::CException(-4,ss.str(), __PRETTY_FUNCTION__);
-
-        }
-        uint64_t tmp=pow(2,(uint32_t)log2(timeError_opt));
-        timePrecisionMask=~(tmp-1);
-        if(getGlobalConfigurationInstance()->hasOption(OPT_CACHE_DRIVER_KVP)) {
-            GlobalConfiguration::fillKVParameter(setting.cache_driver_setting.key_value_custom_param,
-                                                                getGlobalConfigurationInstance()->getOption< std::vector<std::string> >(OPT_CACHE_DRIVER_KVP), "");
-//            fillKVParameter(setting.cache_driver_setting.key_value_custom_param,
-//                            getGlobalConfigurationInstance()->getOption< std::vector<std::string> >(OPT_CACHE_DRIVER_KVP));
-        }
-        
-        if(getGlobalConfigurationInstance()->hasOption(OPT_OBJ_STORAGE_DRIVER_KVP)) {
-            GlobalConfiguration::fillKVParameter(setting.object_storage_setting.key_value_custom_param,
-                                                                getGlobalConfigurationInstance()->getOption< std::vector<std::string> >(OPT_OBJ_STORAGE_DRIVER_KVP), "");
-//            fillKVParameter(setting.object_storage_setting.key_value_custom_param,
-//                            getGlobalConfigurationInstance()->getOption< std::vector<std::string> >(OPT_OBJ_STORAGE_DRIVER_KVP));
-        }
-         if(getGlobalConfigurationInstance()->hasOption(OPT_LOG_STORAGE_DRIVER_KVP)) {
-            GlobalConfiguration::fillKVParameter(setting.log_storage_setting.key_value_custom_param,
-                                                                getGlobalConfigurationInstance()->getOption< std::vector<std::string> >(OPT_LOG_STORAGE_DRIVER_KVP), "");
-//            fillKVParameter(setting.object_storage_setting.key_value_custom_param,
-//                            getGlobalConfigurationInstance()->getOption< std::vector<std::string> >(OPT_OBJ_STORAGE_DRIVER_KVP));
-        }
-        //initilize driver pool manager
-        DriverPoolManager::persistentSetting.persistence_implementation=setting.persistence_implementation;
-        DriverPoolManager::persistentSetting.persistence_kv_param_map=setting.persistence_kv_param_map;
-        DriverPoolManager::persistentSetting.persistence_server_list=setting.persistence_server_list;
-
-        DriverPoolManager::cacheSetting.cache_driver_impl=setting.cache_driver_setting.cache_driver_impl;
-        DriverPoolManager::cacheSetting.startup_chache_servers=setting.cache_driver_setting.startup_chache_servers;
-        DriverPoolManager::cacheSetting.caching_pool_min_instances_number=setting.cache_driver_setting.caching_pool_min_instances_number;
-        DriverPoolManager::cacheSetting.log_metric=setting.cache_driver_setting.log_metric;
-        DriverPoolManager::cacheSetting.key_value_custom_param=setting.cache_driver_setting.key_value_custom_param;
-
-        DriverPoolManager::logSetting.persistence_kv_param_map=setting.log_storage_setting.key_value_custom_param;
-        DriverPoolManager::logSetting.persistence_implementation=setting.log_storage_setting.driver_impl;
-        DriverPoolManager::logSetting.persistence_server_list=setting.log_storage_setting.url_list;
-
-        DriverPoolManager::objectSetting.persistence_kv_param_map=setting.object_storage_setting.key_value_custom_param;
-        DriverPoolManager::objectSetting.persistence_implementation=setting.object_storage_setting.driver_impl;
-        DriverPoolManager::objectSetting.persistence_server_list=setting.object_storage_setting.url_list;
-        
-        InizializableService::initImplementation(DriverPoolManager::getInstance(), NULL, "DriverPoolManager", __PRETTY_FUNCTION__);
-        
-        //! batch system
-        StartableService::initImplementation(MDSBatchExecutor::getInstance(), NULL, "MDSBatchExecutor", __PRETTY_FUNCTION__);
-        
-        //api system
-        api_managment_service.reset(new ApiManagment(), "ApiManagment");
-        api_managment_service.init(NULL, __PRETTY_FUNCTION__);
+void ChaosMetadataService::init(void* init_data) {
+  try {
+     getGlobalConfigurationInstance()->getConfiguration()->addBoolValue("ismds",true);
+   std::string gname;
+   if(getGlobalConfigurationInstance()->hasOption(InitOption::OPT_GROUP_NAME)){
+    gname=getGlobalConfigurationInstance()->getOption<std::string>(InitOption::OPT_GROUP_NAME);
+   }
+   if(gname.size()){
+    getGlobalConfigurationInstance()->getConfiguration()->addStringValue(InitOption::OPT_GROUP_NAME,gname);
+   } else {
+     getGlobalConfigurationInstance()->getConfiguration()->addStringValue(InitOption::OPT_GROUP_NAME,CDS_GROUP_NAME);
+   }
+    ChaosCommon<ChaosMetadataService>::init(init_data);
+
+    if (signal((int)SIGINT, ChaosMetadataService::signalHanlder) == SIG_ERR) {
+      throw CException(-1, "Error registering SIGINT signal", __PRETTY_FUNCTION__);
+    }
+
+    if (signal((int)SIGQUIT, ChaosMetadataService::signalHanlder) == SIG_ERR) {
+      throw CException(-2, "Error registering SIG_ERR signal", __PRETTY_FUNCTION__);
+    }
+
+    if (signal((int)SIGTERM, ChaosMetadataService::signalHanlder) == SIG_ERR) {
+      throw CException(-3, "Error registering SIGTERM signal", __PRETTY_FUNCTION__);
+    }
+
+    // scan the setting
+    if (!setting.persistence_implementation.size()) {
+      // no cache server provided
+      throw chaos::CException(-3, "No persistence implementation provided", __PRETTY_FUNCTION__);
+    }
+
+    if (!setting.persistence_server_list.size()) {
+      // no cache server provided
+      throw chaos::CException(-4, "No persistence's server list provided", __PRETTY_FUNCTION__);
+    }
+  
+
+    if (getGlobalConfigurationInstance()->hasOption(chaos::service_common::persistence::OPT_PERSITENCE_KV_PARAMTER)) {
+      fillKVParameter(setting.persistence_kv_param_map,
+                      getGlobalConfigurationInstance()->getOption<std::vector<std::string> >(chaos::service_common::persistence::OPT_PERSITENCE_KV_PARAMTER));
+    }
+
+    // check for mandatory configuration
+    if (!getGlobalConfigurationInstance()->hasOption(OPT_CACHE_SERVER_LIST)) {
+      // no cache server provided
+      throw chaos::CException(-3, "No cache server provided", __PRETTY_FUNCTION__);
+    }
+
+    if (getGlobalConfigurationInstance()->hasOption(OPT_SYNCTIME_ERROR)) {
+      timeError_opt = getGlobalConfigurationInstance()->getOption<uint32_t>(OPT_SYNCTIME_ERROR);
+    }
+
+    if (timeError_opt > 2048) {
+      std::stringstream ss;
+      ss << "Specified time synchronization error to high:" << timeError_opt << " ms";
+      throw chaos::CException(-4, ss.str(), __PRETTY_FUNCTION__);
+    }
+    uint64_t tmp      = pow(2, (uint32_t)log2(timeError_opt));
+    timePrecisionMask = ~(tmp - 1);
+    is_present        = false;
+    if (getGlobalConfigurationInstance()->hasOption(OPT_CACHE_DRIVER_KVP)) {
+      GlobalConfiguration::fillKVParameter(setting.cache_driver_setting.key_value_custom_param,
+                                           getGlobalConfigurationInstance()->getOption<std::vector<std::string> >(OPT_CACHE_DRIVER_KVP),
+                                           "");
+      //            fillKVParameter(setting.cache_driver_setting.key_value_custom_param,
+      //                            getGlobalConfigurationInstance()->getOption< std::vector<std::string> >(OPT_CACHE_DRIVER_KVP));
+    }
+
+    if (getGlobalConfigurationInstance()->hasOption(OPT_OBJ_STORAGE_DRIVER_KVP)) {
+      GlobalConfiguration::fillKVParameter(setting.object_storage_setting.key_value_custom_param,
+                                           getGlobalConfigurationInstance()->getOption<std::vector<std::string> >(OPT_OBJ_STORAGE_DRIVER_KVP),
+                                           "");
+      //            fillKVParameter(setting.object_storage_setting.key_value_custom_param,
+      //                            getGlobalConfigurationInstance()->getOption< std::vector<std::string> >(OPT_OBJ_STORAGE_DRIVER_KVP));
+    }
+    if (getGlobalConfigurationInstance()->hasOption(OPT_LOG_STORAGE_DRIVER_KVP)) {
+      GlobalConfiguration::fillKVParameter(setting.log_storage_setting.key_value_custom_param,
+                                           getGlobalConfigurationInstance()->getOption<std::vector<std::string> >(OPT_LOG_STORAGE_DRIVER_KVP),
+                                           "");
+      //            fillKVParameter(setting.object_storage_setting.key_value_custom_param,
+      //                            getGlobalConfigurationInstance()->getOption< std::vector<std::string> >(OPT_OBJ_STORAGE_DRIVER_KVP));
+    }
+    // initilize driver pool manager
+    DriverPoolManager::persistentSetting.persistence_implementation = setting.persistence_implementation;
+    DriverPoolManager::persistentSetting.persistence_kv_param_map   = setting.persistence_kv_param_map;
+    DriverPoolManager::persistentSetting.persistence_server_list    = setting.persistence_server_list;
+
+    DriverPoolManager::cacheSetting.cache_driver_impl                 = setting.cache_driver_setting.cache_driver_impl;
+    DriverPoolManager::cacheSetting.startup_chache_servers            = setting.cache_driver_setting.startup_chache_servers;
+    DriverPoolManager::cacheSetting.caching_pool_min_instances_number = setting.cache_driver_setting.caching_pool_min_instances_number;
+    DriverPoolManager::cacheSetting.log_metric                        = setting.cache_driver_setting.log_metric;
+    DriverPoolManager::cacheSetting.key_value_custom_param            = setting.cache_driver_setting.key_value_custom_param;
+
+    DriverPoolManager::logSetting.persistence_kv_param_map   = setting.log_storage_setting.key_value_custom_param;
+    DriverPoolManager::logSetting.persistence_implementation = setting.log_storage_setting.driver_impl;
+    DriverPoolManager::logSetting.persistence_server_list    = setting.log_storage_setting.url_list;
+
+    DriverPoolManager::objectSetting.persistence_kv_param_map   = setting.object_storage_setting.key_value_custom_param;
+    DriverPoolManager::objectSetting.persistence_implementation = setting.object_storage_setting.driver_impl;
+    DriverPoolManager::objectSetting.persistence_server_list    = setting.object_storage_setting.url_list;
+
+    InizializableService::initImplementation(DriverPoolManager::getInstance(), NULL, "DriverPoolManager", __PRETTY_FUNCTION__);
+
+    //! batch system
+    StartableService::initImplementation(MDSBatchExecutor::getInstance(), NULL, "MDSBatchExecutor", __PRETTY_FUNCTION__);
+
+    // api system
+    api_managment_service.reset(new ApiManagment(), "ApiManagment");
+    api_managment_service.init(NULL, __PRETTY_FUNCTION__);
 #if defined(KAFKA_RDK_ENABLE) || defined(KAFKA_ASIO_ENABLE)
 #warning "CDS NEEDS KAFKA"
-        message_consumer.reset(new QueryDataMsgPSConsumer("cds"), "QueryDataMsgPSConsumer");        
-        if(!message_consumer.get()) throw chaos::CException(-7, "Error instantiating message data consumer", __PRETTY_FUNCTION__);
-        message_consumer.init(NULL, __PRETTY_FUNCTION__);
-#endif        
-        data_consumer.reset(new QueryDataConsumer(), "QueryDataConsumer");
-
-        if(!data_consumer.get()) throw chaos::CException(-7, "Error instantiating data consumer", __PRETTY_FUNCTION__);
-        data_consumer.init(NULL, __PRETTY_FUNCTION__);
-        
-        //initialize cron manager
-        InizializableService::initImplementation(cron_job::MDSCronusManager::getInstance(),
-                                                 NULL,
-                                                 "MDSConousManager",
-                                                 __PRETTY_FUNCTION__);
-
-        InizializableService::initImplementation(SharedManagedDirecIoDataDriver::getInstance(), NULL, "SharedManagedDirecIoDataDriver", __PRETTY_FUNCTION__);
-
-        StartableService::initImplementation(HealtManagerDirect::getInstance(), NULL, "HealtManagerDirect", __PRETTY_FUNCTION__);
-
-        
-    } catch (CException& ex) {
-        DECODE_CHAOS_EXCEPTION(ex)
-        exit(1);
-    }
-    //start data manager
+    message_consumer.reset(new QueryDataMsgPSConsumer(CDS_GROUP_NAME), "QueryDataMsgPSConsumer");
+    if (!message_consumer.get()) throw chaos::CException(-7, "Error instantiating message data consumer", __PRETTY_FUNCTION__);
+    message_consumer.init(NULL, __PRETTY_FUNCTION__);
+#endif
+    data_consumer.reset(new QueryDataConsumer(), "QueryDataConsumer");
+
+    if (!data_consumer.get()) throw chaos::CException(-7, "Error instantiating data consumer", __PRETTY_FUNCTION__);
+    data_consumer.init(NULL, __PRETTY_FUNCTION__);
+
+    // initialize cron manager
+    InizializableService::initImplementation(cron_job::MDSCronusManager::getInstance(),
+                                             NULL,
+                                             "MDSConousManager",
+                                             __PRETTY_FUNCTION__);
+
+    InizializableService::initImplementation(SharedManagedDirecIoDataDriver::getInstance(), NULL, "SharedManagedDirecIoDataDriver", __PRETTY_FUNCTION__);
+
+    StartableService::initImplementation(HealtManagerDirect::getInstance(), NULL, "HealtManagerDirect", __PRETTY_FUNCTION__);
+
+  } catch (CException& ex) {
+    DECODE_CHAOS_EXCEPTION(ex)
+    exit(1);
+  }
+  // start data manager
 }
 
-int ChaosMetadataService::notifyNewNode(const std::string& nodeuid){
-    LCND_LDBG<<" NEW NODE:"<<nodeuid;
-    return message_consumer->consumeHealthDataEvent(nodeuid, 0, ChaosStringSetConstSPtr(),  ChaosMakeSharedPtr<Buffer>());
-
+int ChaosMetadataService::notifyNewNode(const std::string& nodeuid) {
+  LCND_LDBG << " NEW NODE:" << nodeuid;
+  return message_consumer->consumeHealthDataEvent(nodeuid, 0, ChaosStringSetConstSPtr(), ChaosMakeSharedPtr<Buffer>());
 }
 
 /*
  *
  */
-void ChaosMetadataService::start()  {
-    //lock o monitor for waith the end
-    try {
-        ChaosCommon<ChaosMetadataService>::start();
-        StartableService::startImplementation(MDSBatchExecutor::getInstance(), "MDSBatchExecutor", __PRETTY_FUNCTION__);
-        #if defined(KAFKA_RDK_ENABLE) || defined(KAFKA_ASIO_ENABLE)
-        message_consumer.start( __PRETTY_FUNCTION__);
-
-        #endif
-        //start batch system
-        data_consumer.start( __PRETTY_FUNCTION__);
-        LAPP_ <<"\n----------------------------------------------------------------------"<<
-        "\n!CHAOS Metadata service started" <<
-        "\nRPC Server address: "	<< NetworkBroker::getInstance()->getRPCUrl() <<
-        "\nDirectIO Server address: " << NetworkBroker::getInstance()->getDirectIOUrl() <<
-        CHAOS_FORMAT("\nData Service published with url: %1%|0", %NetworkBroker::getInstance()->getDirectIOUrl()) <<
-        "\nTime precision mask: "<<std::hex<<timePrecisionMask<<std::dec<<"\n----------------------------------------------------------------------";
-        
-        //register this process on persistence database
-        persistence::data_access::DataServiceDataAccess *ds_da = DriverPoolManager::getInstance()->getPersistenceDataAccess<persistence::data_access::DataServiceDataAccess>();
-        std::string unique_uid=NetworkBroker::getInstance()->getRPCUrl();
-        ds_da->registerNode(setting.ha_zone_name,
-                            unique_uid,
-                            NetworkBroker::getInstance()->getDirectIOUrl(),
-                            0,getBuildInfo(chaos::common::data::CDWUniquePtr()));
-
-        //at this point i must with for end signal
-        chaos::common::async_central::AsyncCentralManager::getInstance()->addTimer(this,
-                                                                                   0,
-                                                                                   chaos::common::constants::HBTimersTimeoutinMSec);
-
-
-        StartableService::startImplementation(HealtManagerDirect::getInstance(), "HealtManagerDirect", __PRETTY_FUNCTION__);
-        HealtManagerDirect::getInstance()->addNewNode(unique_uid);
-        HealtManagerDirect::getInstance()->addNodeMetricValue(unique_uid,
-                                                            NodeHealtDefinitionKey::NODE_HEALT_STATUS,
-                                                            NodeHealtDefinitionValue::NODE_HEALT_STATUS_START);
-            
-        waitCloseSemaphore.wait();
-    } catch (CException& ex) {
-        DECODE_CHAOS_EXCEPTION(ex)
-    }
-    //execute the deinitialization of CU
-    try{
-        stop();
-    } catch (CException& ex) {
-        DECODE_CHAOS_EXCEPTION(ex)
-    }
-    
-    try{
-        deinit();
-    } catch (CException& ex) {
-        DECODE_CHAOS_EXCEPTION(ex)
-    }
+void ChaosMetadataService::start() {
+  // lock o monitor for waith the end
+  try {
+    ChaosCommon<ChaosMetadataService>::start();
+    StartableService::startImplementation(MDSBatchExecutor::getInstance(), "MDSBatchExecutor", __PRETTY_FUNCTION__);
+
+    // start batch system
+    data_consumer.start(__PRETTY_FUNCTION__);
+    LAPP_ << "\n----------------------------------------------------------------------"
+          << "\n!CHAOS Metadata service started"
+          << "\nRPC Server address: " << NetworkBroker::getInstance()->getRPCUrl() << "\nDirectIO Server address: " << NetworkBroker::getInstance()->getDirectIOUrl() << CHAOS_FORMAT("\nData Service published with url: %1%", % NetworkBroker::getInstance()->getDirectIOUrl()) << "\nTime precision mask: " << std::hex << timePrecisionMask << std::dec << "\n----------------------------------------------------------------------";
+
+    // register this process on persistence database
+    persistence::data_access::DataServiceDataAccess* ds_da      = DriverPoolManager::getInstance()->getPersistenceDataAccess<persistence::data_access::DataServiceDataAccess>();
+    LCND_LDBG << "-----REGISTERING "<<nodeuid;
+    chaos::common::data::CDWUniquePtr info=getBuildInfo(chaos::common::data::CDWUniquePtr());
+    info->addStringValue(NodeDefinitionKey::NODE_IP_ADDR,
+                           chaos::GlobalConfiguration::getInstance()->getLocalServerAddressAnBasePort());
+    ds_da->registerNode(setting.ha_zone_name,
+                        nodeuid,
+                        NetworkBroker::getInstance()->getDirectIOUrl(),
+                        0,
+                        MOVE(info));
+
+    // at this point i must with for end signal
+    chaos::common::async_central::AsyncCentralManager::getInstance()->addTimer(this,
+                                                                               0,
+                                                                               chaos::common::constants::HBTimersTimeoutinMSec);
+
+    StartableService::startImplementation(HealtManagerDirect::getInstance(), "HealtManagerDirect", __PRETTY_FUNCTION__);
+    HealtManagerDirect::getInstance()->addNewNode(nodeuid);
+    HealtManagerDirect::getInstance()->addNodeMetricValue(nodeuid,
+                                                          NodeHealtDefinitionKey::NODE_HEALT_STATUS,
+                                                          NodeHealtDefinitionValue::NODE_HEALT_STATUS_START);
+#if defined(KAFKA_RDK_ENABLE) || defined(KAFKA_ASIO_ENABLE)
+
+    sleep(chaos::common::constants::HBTimersTimeoutinMSec / 1000);
+    LCND_LDBG << "-----SUBSCRIBING---";
+
+    message_consumer.start(__PRETTY_FUNCTION__);
+
+#endif
+
+    waitCloseSemaphore.wait();
+  } catch (CException& ex) {
+    DECODE_CHAOS_EXCEPTION(ex)
+  }
+  // execute the deinitialization of CU
+  try {
+    stop();
+  } catch (CException& ex) {
+    DECODE_CHAOS_EXCEPTION(ex)
+  }
+
+  try {
+    deinit();
+  } catch (CException& ex) {
+    DECODE_CHAOS_EXCEPTION(ex)
+  }
 }
 
 void ChaosMetadataService::timeout() {
-    int err = 0;
+  int                                              err = 0;
+  HealthStat                                       service_proc_stat;
+  persistence::data_access::DataServiceDataAccess* ds_da  = DriverPoolManager::getInstance()->getPersistenceDataAccess<persistence::data_access::DataServiceDataAccess>();
+  persistence::data_access::NodeDataAccess*        n_da   = DriverPoolManager::getInstance()->getPersistenceDataAccess<persistence::data_access::NodeDataAccess>();
+  service_proc_stat.mds_received_timestamp                = TimingUtil::getTimeStamp();
+  if (is_present == false) {
     bool presence = false;
-    HealthStat service_proc_stat;
-    const std::string ds_uid = NetworkBroker::getInstance()->getRPCUrl();
-    persistence::data_access::DataServiceDataAccess *ds_da = DriverPoolManager::getInstance()->getPersistenceDataAccess<persistence::data_access::DataServiceDataAccess>();
-    persistence::data_access::NodeDataAccess *n_da = DriverPoolManager::getInstance()->getPersistenceDataAccess<persistence::data_access::NodeDataAccess>();
-    service_proc_stat.mds_received_timestamp = TimingUtil::getTimeStamp();
-    if(n_da->checkNodePresence(presence, ds_uid) != 0) {
-        LCND_LERR << CHAOS_FORMAT("Error check if this mds [%1%] description is registered", %NetworkBroker::getInstance()->getRPCUrl());
-        return;
+    if (n_da->checkNodePresence(presence, nodeuid) != 0) {
+      LCND_LERR << CHAOS_FORMAT("Error check if this mds [%1%] description is registered", % nodeuid);
+      // return;
     }
 
-    if(presence == false) {
-        //reinsert mds
-        ds_da->registerNode(setting.ha_zone_name,
-                            NetworkBroker::getInstance()->getRPCUrl(),
-                            NetworkBroker::getInstance()->getDirectIOUrl(),
-                            0,
-                            getBuildInfo(chaos::common::data::CDWUniquePtr()));
-    }
-
-    //update proc stat
-    ProcStatCalculator::update(service_proc_stat);
-    if((err = n_da->setNodeHealthStatus(NetworkBroker::getInstance()->getRPCUrl(),
-                                        service_proc_stat))) {
-        LCND_LERR << CHAOS_FORMAT("error storing health data into database for this mds [%1%]", %NetworkBroker::getInstance()->getRPCUrl());
+    if (presence == false) {
+      // reinsert mds
+      ds_da->registerNode(setting.ha_zone_name,
+                          nodeuid,
+                          NetworkBroker::getInstance()->getDirectIOUrl(),
+                          0,
+                          getBuildInfo(chaos::common::data::CDWUniquePtr()));
     }
+    is_present = presence;
+  }
+
+  // update proc stat
+  ProcStatCalculator::update(service_proc_stat);
+  if ((err = n_da->setNodeHealthStatus(nodeuid,
+                                       service_proc_stat))) {
+    LCND_LERR << CHAOS_FORMAT("error storing health data into database for this mds [%1%]", % NetworkBroker::getInstance()->getRPCUrl());
+  }
 }
 
-bool ChaosMetadataService::isNodeAlive(const std::string& uid){
-    ChaosStringVector s;
-    s.push_back(uid);
-    bool alive=areNodeAlive(s)[0];
-    //LCND_LDBG<<"NODE:"<<uid<<" "<<((alive)?"TRUE":"FALSE");
-    return alive;
-    }
+bool ChaosMetadataService::isNodeAlive(const std::string& uid) {
+  ChaosStringVector s;
+  uint64_t          now = chaos::common::utility::TimingUtil::getTimeStamp();
+  if (alive_cache.count(uid)){
+      if((alive_cache[uid] >= (now - (2 * chaos::common::constants::HBTimersTimeoutinMSec)))){
+       // LCND_LDBG << uid<<" found in cache";
+
+        return true;
+      } 
+  }  
+  s.push_back(uid);
+  bool alive = areNodeAlive(s)[0];
+  // LCND_LDBG<<"NODE:"<<uid<<" "<<((alive)?"TRUE":"FALSE");
+  return alive;
+}
 using namespace chaos::metadata_service::object_storage::abstraction;
 using namespace chaos::metadata_service::persistence::data_access;
 
-int ChaosMetadataService::removeStorageData(const std::string& control_unit_found,uint64_t start,uint64_t remove_until_ts){
-    int err;
-    auto *obj_storage_da = DriverPoolManager::getInstance()->getObjectStorageDrv().getDataAccess<ObjectStorageDataAccess>();
+int ChaosMetadataService::removeStorageData(const std::string& control_unit_found, uint64_t start, uint64_t remove_until_ts) {
+  int   err;
+  auto* obj_storage_da = DriverPoolManager::getInstance()->getObjectStorageDrv().getDataAccess<ObjectStorageDataAccess>();
+
+  if (obj_storage_da == NULL) {
+    LCND_LERR << " cannot access object storage resources";
+    return -1;
+  }
+  LCND_LDBG << " deleting node storage " << control_unit_found << " from:" << start << " to:" << remove_until_ts;
+  const std::string output_key = control_unit_found + DataPackPrefixID::OUTPUT_DATASET_POSTFIX;
+  const std::string input_key  = control_unit_found + DataPackPrefixID::INPUT_DATASET_POSTFIX;
+  const std::string system_key = control_unit_found + DataPackPrefixID::SYSTEM_DATASET_POSTFIX;
+  const std::string custom_key = control_unit_found + DataPackPrefixID::CUSTOM_DATASET_POSTFIX;
+  // const std::string health_key    = control_unit_found + NodeHealtDefinitionKey::HEALT_KEY_POSTFIX;
+  const std::string dev_alarm_key = control_unit_found + DataPackPrefixID::DEV_ALARM_DATASET_POSTFIX;
+  const std::string cu_alarm_key  = control_unit_found + DataPackPrefixID::CU_ALARM_DATASET_POSTFIX;
+
+  try {
+    log(CHAOS_FORMAT("Remove data for key %1%", % output_key));
+
+    if ((err = obj_storage_da->deleteObject(output_key,
+                                            start,
+                                            remove_until_ts))) {
+      log(CHAOS_FORMAT("Error erasing key %1% for control unit %2% with error %3%", % output_key % control_unit_found % err));
+    }
+
+    log(CHAOS_FORMAT("Remove data for key %1%", % input_key));
+    if ((err = obj_storage_da->deleteObject(input_key,
+                                            start,
+                                            remove_until_ts))) {
+      log(CHAOS_FORMAT("Error erasing key %1% for control unit %2% with error %3%", % input_key % control_unit_found % err));
+    }
+
+    log(CHAOS_FORMAT("Remove data for key %1%", % system_key));
+    if ((err = obj_storage_da->deleteObject(system_key,
+                                            start,
+                                            remove_until_ts))) {
+      log(CHAOS_FORMAT("Error erasing key %1% for control unit %2% with error %3%", % system_key % control_unit_found % err));
+    }
+
+    log(CHAOS_FORMAT("Remove data for key %1%", % custom_key));
+    if ((err = obj_storage_da->deleteObject(custom_key,
+                                            start,
+                                            remove_until_ts))) {
+      log(CHAOS_FORMAT("Error erasing key %1% for control unit %2% with error %3%", % custom_key % control_unit_found % err));
+    }
+
+    /*  log(CHAOS_FORMAT("Remove data for key %1%", %health_key));
+      if((err = obj_storage_da->deleteObject(health_key,
+                                             start,
+                                             remove_until_ts))){
+          log(CHAOS_FORMAT("Error erasing key %1% for control unit %2% with error %3%", %health_key%control_unit_found%err));
+      }
+      */
+    log(CHAOS_FORMAT("Remove data for key %1%", % dev_alarm_key));
+    if ((err = obj_storage_da->deleteObject(dev_alarm_key,
+                                            start,
+                                            remove_until_ts))) {
+      log(CHAOS_FORMAT("Error erasing key %1% for control unit %2% with error %3%", % dev_alarm_key % control_unit_found % err));
+    }
 
-    if(obj_storage_da==NULL ){
-        LCND_LERR<< " cannot access object storage resources";
-        return -1;
+    log(CHAOS_FORMAT("Remove data for key %1%", % cu_alarm_key));
+    if ((err = obj_storage_da->deleteObject(cu_alarm_key,
+                                            start,
+                                            remove_until_ts))) {
+      log(CHAOS_FORMAT("Error erasing key %1% for control unit %2% with error %3%", % cu_alarm_key % control_unit_found % err));
     }
-    LCND_LDBG<<" deleting node storage "<<control_unit_found<<" from:"<<start<<" to:"<<remove_until_ts;
-      const std::string output_key    = control_unit_found + DataPackPrefixID::OUTPUT_DATASET_POSTFIX;
-        const std::string input_key     = control_unit_found + DataPackPrefixID::INPUT_DATASET_POSTFIX;
-        const std::string system_key    = control_unit_found + DataPackPrefixID::SYSTEM_DATASET_POSTFIX;
-        const std::string custom_key    = control_unit_found + DataPackPrefixID::CUSTOM_DATASET_POSTFIX;
-       // const std::string health_key    = control_unit_found + NodeHealtDefinitionKey::HEALT_KEY_POSTFIX;
-        const std::string dev_alarm_key    = control_unit_found + DataPackPrefixID::DEV_ALARM_DATASET_POSTFIX;
-        const std::string cu_alarm_key    = control_unit_found + DataPackPrefixID::CU_ALARM_DATASET_POSTFIX;
-      
-       try {
-            log(CHAOS_FORMAT("Remove data for key %1%", %output_key));
-            
-            if((err = obj_storage_da->deleteObject(output_key,
-                                                   start,
-                                                   remove_until_ts))){
-                log(CHAOS_FORMAT("Error erasing key %1% for control unit %2% with error %3%", %output_key%control_unit_found%err));
-            }
-            
-            log(CHAOS_FORMAT("Remove data for key %1%", %input_key));
-            if((err = obj_storage_da->deleteObject(input_key,
-                                                   start,
-                                                   remove_until_ts))){
-                log(CHAOS_FORMAT("Error erasing key %1% for control unit %2% with error %3%", %input_key%control_unit_found%err));
-            }
-            
-            log(CHAOS_FORMAT("Remove data for key %1%", %system_key));
-            if((err = obj_storage_da->deleteObject(system_key,
-                                                   start,
-                                                   remove_until_ts))){
-                log(CHAOS_FORMAT("Error erasing key %1% for control unit %2% with error %3%", %system_key%control_unit_found%err));
-            }
-            
-            log(CHAOS_FORMAT("Remove data for key %1%", %custom_key));
-            if((err = obj_storage_da->deleteObject(custom_key,
-                                                   start,
-                                                   remove_until_ts))){
-                log(CHAOS_FORMAT("Error erasing key %1% for control unit %2% with error %3%", %custom_key%control_unit_found%err));
-            }
-            
-          /*  log(CHAOS_FORMAT("Remove data for key %1%", %health_key));
-            if((err = obj_storage_da->deleteObject(health_key,
-                                                   start,
-                                                   remove_until_ts))){
-                log(CHAOS_FORMAT("Error erasing key %1% for control unit %2% with error %3%", %health_key%control_unit_found%err));
-            }
-            */
-            log(CHAOS_FORMAT("Remove data for key %1%", %dev_alarm_key));
-            if((err = obj_storage_da->deleteObject(dev_alarm_key,
-                                                   start,
-                                                   remove_until_ts))){
-                log(CHAOS_FORMAT("Error erasing key %1% for control unit %2% with error %3%", %dev_alarm_key%control_unit_found%err));
-            }
-            
-            log(CHAOS_FORMAT("Remove data for key %1%", %cu_alarm_key));
-            if((err = obj_storage_da->deleteObject(cu_alarm_key,
-                                                   start,
-                                                   remove_until_ts))){
-                log(CHAOS_FORMAT("Error erasing key %1% for control unit %2% with error %3%", %cu_alarm_key%control_unit_found%err));
-            }
-            
-            log(CHAOS_FORMAT("Remove log for cu %1%", %control_unit_found));
-            if((err = DriverPoolManager::getInstance()->getPersistenceDataAccess<persistence::data_access::LoggingDataAccess>()->eraseLogBeforTS(control_unit_found,
-                                                                                                    remove_until_ts))){
-                log(CHAOS_FORMAT("Error erasing logging for control unit %1% with error %2%", %control_unit_found%err));
-            }
-            }catch(CException& ex){
-            log(ex.what());
-            return -100;
-        }catch(...){
-            log("Undeterminated error during ageing management");
-            return -200;
-        }
-    return err;
 
+    log(CHAOS_FORMAT("Remove log for cu %1%", % control_unit_found));
+    if ((err = DriverPoolManager::getInstance()->getPersistenceDataAccess<persistence::data_access::LoggingDataAccess>()->eraseLogBeforTS(control_unit_found,
+                                                                                                                                          remove_until_ts))) {
+      log(CHAOS_FORMAT("Error erasing logging for control unit %1% with error %2%", % control_unit_found % err));
+    }
+  } catch (CException& ex) {
+    log(ex.what());
+    return -100;
+  } catch (...) {
+    log("Undeterminated error during ageing management");
+    return -200;
+  }
+  return err;
+}
+static boost::mutex mutex_cache;
+void                ChaosMetadataService::updateLiveCache(const chaos::common::data::CDataWrapper* d) {
+  if (d && d->hasKey(DataPackCommonKey::DPCK_TIMESTAMP) && d->hasKey(chaos::NodeDefinitionKey::NODE_UNIQUE_ID)) {
+    std::string  name = d->getStringValue(chaos::NodeDefinitionKey::NODE_UNIQUE_ID);
+    updateLiveCache(name,d->getInt64Value(DataPackCommonKey::DPCK_TIMESTAMP));
+  }
+}
+void  ChaosMetadataService::updateLiveCache(const std::string& name,int64_t t) {
+       boost::lock_guard<boost::mutex> l(mutex_cache);
+    if (alive_cache.count(name)) {
+      if (alive_cache[name] < t) {
+         //   LCND_LDBG << name<<" updated cache";
+
+        alive_cache[name] = t;
+      }
+    } else {
+      alive_cache[name] = t;
+    }
+ 
 }
 
-std::vector<bool> ChaosMetadataService::areNodeAlive(const ChaosStringVector& uids){
-        int err=0;
-        std::vector<bool> res;
-        CacheDriver& cache_slot = DriverPoolManager::getInstance()->getCacheDrv();
-        DataBuffer data_buffer;
-        MultiCacheData multi_cached_data;
-        ChaosStringVector keys;
-        for(ChaosStringVector::const_iterator i=uids.begin();i!=uids.end();i++){
-            keys.push_back((*i)+NodeHealtDefinitionKey::HEALT_KEY_POSTFIX);
-        }
-        if(keys.size()==0) return res;
-        err = cache_slot.getData(keys,
-                                 multi_cached_data);
-        uint64_t now=chaos::common::utility::TimingUtil::getTimeStamp();
-        for(ChaosStringVectorConstIterator it = keys.begin(),
-            end = keys.end();
-            it != end;
-            it++) {
-            const CacheData& cached_element = multi_cached_data[*it];
-            if(!cached_element ||
-               cached_element->size() == 0) {
-                res.push_back(false);
-            } else {
-                CDataWrapper ca(cached_element->data(),cached_element->size());
-                uint64_t ts=0;
-                if(ca.hasKey(NodeHealtDefinitionKey::NODE_HEALT_MDS_TIMESTAMP)){
-                    ts=ca.getInt64Value(NodeHealtDefinitionKey::NODE_HEALT_MDS_TIMESTAMP);
-                } else if(ca.hasKey(DataPackCommonKey::DPCK_TIMESTAMP)){
-                    ts=ca.getInt64Value(DataPackCommonKey::DPCK_TIMESTAMP);
-                }
-                 res.push_back((ts>(now-(2*chaos::common::constants::HBTimersTimeoutinMSec))));
-
-            }
-        }
-        return res;
-    
+std::vector<bool> ChaosMetadataService::areNodeAlive(const ChaosStringVector& uids) {
+  int               err = 0;
+  std::vector<bool> res;
+  CacheDriver&      cache_slot = DriverPoolManager::getInstance()->getCacheDrv();
+  DataBuffer        data_buffer;
+  MultiCacheData    multi_cached_data;
+  ChaosStringVector keys;
+  uint64_t          now = chaos::common::utility::TimingUtil::getTimeStamp();
+
+  for (ChaosStringVector::const_iterator i = uids.begin(); i != uids.end(); i++) {
+    if ((alive_cache.count(*i) == 0)) {
+      keys.push_back((*i) + NodeHealtDefinitionKey::HEALT_KEY_POSTFIX);
+    } else if (alive_cache[*i] < (now - (2 * chaos::common::constants::HBTimersTimeoutinMSec))) {
+      keys.push_back((*i) + NodeHealtDefinitionKey::HEALT_KEY_POSTFIX);
+    } else {
+      res.push_back(true);
+    }
+  }
+  if (keys.size() == 0) return res;
+  err = cache_slot.getData(keys,
+                           multi_cached_data);
+  for (ChaosStringVectorConstIterator it  = keys.begin(),
+                                      end = keys.end();
+       it != end;
+       it++) {
+    const CacheData& cached_element = multi_cached_data[*it];
+    if (!cached_element ||
+        cached_element->size() == 0) {
+      res.push_back(false);
+    } else {
+      CDataWrapper ca(cached_element->data(), cached_element->size());
+      uint64_t     ts = 0;
+      if (ca.hasKey(NodeHealtDefinitionKey::NODE_HEALT_MDS_TIMESTAMP)) {
+        ts = ca.getInt64Value(NodeHealtDefinitionKey::NODE_HEALT_MDS_TIMESTAMP);
+      } else if (ca.hasKey(DataPackCommonKey::DPCK_TIMESTAMP)) {
+        ts = ca.getInt64Value(DataPackCommonKey::DPCK_TIMESTAMP);
+      }
+      updateLiveCache(*it,ts);
+      res.push_back((ts > (now - (2 * chaos::common::constants::HBTimersTimeoutinMSec))));
+    }
+  }
+  return res;
 }
 
 /*
  Stop the toolkit execution
  */
 void ChaosMetadataService::stop() {
-    CHAOS_NOT_THROW(StartableService::stopImplementation(HealtManagerDirect::getInstance(), "HealtManagerDirect", __PRETTY_FUNCTION__););
-
-    chaos::common::async_central::AsyncCentralManager::getInstance()->removeTimer(this);
-    #if defined(KAFKA_RDK_ENABLE) || defined(KAFKA_ASIO_ENABLE)
-    message_consumer.stop( __PRETTY_FUNCTION__);
-
-    #endif
-    //stop data consumer
-    data_consumer.stop( __PRETTY_FUNCTION__);
-    
-    StartableService::stopImplementation(MDSBatchExecutor::getInstance(), "MDSBatchExecutor", __PRETTY_FUNCTION__);
-    
-    ChaosCommon<ChaosMetadataService>::stop();
-    //endWaithCondition.notify_one();
-    waitCloseSemaphore.unlock();
+  CHAOS_NOT_THROW(StartableService::stopImplementation(HealtManagerDirect::getInstance(), "HealtManagerDirect", __PRETTY_FUNCTION__););
+
+  chaos::common::async_central::AsyncCentralManager::getInstance()->removeTimer(this);
+#if defined(KAFKA_RDK_ENABLE) || defined(KAFKA_ASIO_ENABLE)
+  message_consumer.stop(__PRETTY_FUNCTION__);
+
+#endif
+  // stop data consumer
+  data_consumer.stop(__PRETTY_FUNCTION__);
+
+  StartableService::stopImplementation(MDSBatchExecutor::getInstance(), "MDSBatchExecutor", __PRETTY_FUNCTION__);
+
+  ChaosCommon<ChaosMetadataService>::stop();
+  // endWaithCondition.notify_one();
+  waitCloseSemaphore.unlock();
 }
 
 /*
  Deiniti all the manager
  */
 void ChaosMetadataService::deinit() {
-    InizializableService::deinitImplementation(SharedManagedDirecIoDataDriver::getInstance(), "SharedManagedDirecIoDataDriver", __PRETTY_FUNCTION__);
-
-    CHAOS_NOT_THROW(StartableService::deinitImplementation(HealtManagerDirect::getInstance(), "HealtManagerDirect", __PRETTY_FUNCTION__););
-
-    InizializableService::deinitImplementation(cron_job::MDSCronusManager::getInstance(),
-                                               "MDSConousManager",
-                                               __PRETTY_FUNCTION__);
-    //deinit api system
-    CHAOS_NOT_THROW(api_managment_service.deinit(__PRETTY_FUNCTION__);)
-    if(message_consumer.get()) {
-        message_consumer.deinit(__PRETTY_FUNCTION__);
-    }
-    if(data_consumer.get()) {
-        data_consumer.deinit(__PRETTY_FUNCTION__);
-    }
-    
-    StartableService::deinitImplementation(MDSBatchExecutor::getInstance(), "MDSBatchExecutor", __PRETTY_FUNCTION__);
-    
-    //deinitilize driver pool manager
-    InizializableService::deinitImplementation(DriverPoolManager::getInstance(), "DriverPoolManager", __PRETTY_FUNCTION__);
-    
-    ChaosCommon<ChaosMetadataService>::stop();
-    LAPP_ << "-----------------------------------------";
-    LAPP_ << "Metadata service has been stopped";
-    LAPP_ << "-----------------------------------------";
+  InizializableService::deinitImplementation(SharedManagedDirecIoDataDriver::getInstance(), "SharedManagedDirecIoDataDriver", __PRETTY_FUNCTION__);
+
+  CHAOS_NOT_THROW(StartableService::deinitImplementation(HealtManagerDirect::getInstance(), "HealtManagerDirect", __PRETTY_FUNCTION__););
+
+  InizializableService::deinitImplementation(cron_job::MDSCronusManager::getInstance(),
+                                             "MDSConousManager",
+                                             __PRETTY_FUNCTION__);
+  // deinit api system
+  CHAOS_NOT_THROW(api_managment_service.deinit(__PRETTY_FUNCTION__);)
+  if (message_consumer.get()) {
+    message_consumer.deinit(__PRETTY_FUNCTION__);
+  }
+  if (data_consumer.get()) {
+    data_consumer.deinit(__PRETTY_FUNCTION__);
+  }
+
+  StartableService::deinitImplementation(MDSBatchExecutor::getInstance(), "MDSBatchExecutor", __PRETTY_FUNCTION__);
+
+  // deinitilize driver pool manager
+  InizializableService::deinitImplementation(DriverPoolManager::getInstance(), "DriverPoolManager", __PRETTY_FUNCTION__);
+
+  ChaosCommon<ChaosMetadataService>::stop();
+  LAPP_ << "-----------------------------------------";
+  LAPP_ << "Metadata service has been stopped";
+  LAPP_ << "-----------------------------------------";
 }
 
 /*
  *
  */
 void ChaosMetadataService::signalHanlder(int signalNumber) {
-    waitCloseSemaphore.unlock();
+  waitCloseSemaphore.unlock();
 }
 
 void ChaosMetadataService::fillKVParameter(std::map<std::string, std::string>& kvmap,
-                                           const std::vector<std::string>& multitoken_param) {
-    //! Regular expression for check server endpoint with the sintax hostname:[priority_port:service_port]
-    std::regex KVParamRegex("[a-zA-Z0-9/_-]+:[a-zA-Z0-9/_-]+");
-    std::vector<std::string> kv_splitted;
-    std::vector<std::string> kvtokens;
-    for(std::vector<std::string>::const_iterator it = multitoken_param.begin();
-        it != multitoken_param.end();
-        it++) {
-        
-        const std::string& param_key = *it;
-        
-        
-        
-        if(!std::regex_match(param_key, KVParamRegex)) {
-            throw chaos::CException(-3, "Malformed kv parameter string", __PRETTY_FUNCTION__);
-        }
-        
-        
-        boost::algorithm::split(kvtokens,
-                                param_key,
-                                boost::algorithm::is_any_of("-"),
-                                boost::algorithm::token_compress_on);
-        
-        //clear previosly pair
-        kv_splitted.clear();
-        
-        //get new pair
-        boost::algorithm::split(kv_splitted,
-                                param_key,
-                                boost::algorithm::is_any_of(":"),
-                                boost::algorithm::token_compress_on);
-        // add key/value pair
-        kvmap.insert(std::pair<std::string,std::string>(kv_splitted[0], kv_splitted[1]));
+                                           const std::vector<std::string>&     multitoken_param) {
+  //! Regular expression for check server endpoint with the sintax hostname:[priority_port:service_port]
+  std::regex               KVParamRegex("[a-zA-Z0-9/_-]+:[a-zA-Z0-9/_-]+");
+  std::vector<std::string> kv_splitted;
+  std::vector<std::string> kvtokens;
+  for (std::vector<std::string>::const_iterator it = multitoken_param.begin();
+       it != multitoken_param.end();
+       it++) {
+    const std::string& param_key = *it;
+
+    if (!std::regex_match(param_key, KVParamRegex)) {
+      throw chaos::CException(-3, "Malformed kv parameter string", __PRETTY_FUNCTION__);
     }
+
+    boost::algorithm::split(kvtokens,
+                            param_key,
+                            boost::algorithm::is_any_of("-"),
+                            boost::algorithm::token_compress_on);
+
+    // clear previosly pair
+    kv_splitted.clear();
+
+    // get new pair
+    boost::algorithm::split(kv_splitted,
+                            param_key,
+                            boost::algorithm::is_any_of(":"),
+                            boost::algorithm::token_compress_on);
+    // add key/value pair
+    kvmap.insert(std::pair<std::string, std::string>(kv_splitted[0], kv_splitted[1]));
+  }
 }
diff --git a/ChaosMetadataService/ChaosMetadataService.h b/ChaosMetadataService/ChaosMetadataService.h
index 6fdcbba7f1da7fb6bcd9b657aff4ad1ab5f78e35..f98caad63aeaec960bae0d77151bde41bc479ba1 100644
--- a/ChaosMetadataService/ChaosMetadataService.h
+++ b/ChaosMetadataService/ChaosMetadataService.h
@@ -38,6 +38,7 @@
 #include <chaos/common/thread/WaitSemaphore.h>
 #include <chaos/common/utility/StartableService.h>
 #include <chaos/common/utility/ProcStat.h>
+#define CDS_GROUP_NAME "cds"
 namespace chaos {
     namespace metadata_service {
         //! Chaos Node Directory base class
@@ -65,7 +66,7 @@ namespace chaos {
                                  const std::vector<std::string>& multitoken_param);
             //inherited by chaos::common::async_central::TimerHandler
             void timeout();
-            
+            bool is_present;// check if exists the entry
         public:
             static uint64_t timePrecisionMask;
             static  std::string mdsName;
@@ -95,6 +96,20 @@ namespace chaos {
              */
             std::vector<bool> areNodeAlive(const ChaosStringVector& uids);
             bool isNodeAlive(const std::string& uid);
+            std::map <std::string,int64_t> alive_cache;
+            /**
+             * @brief update alive_cache if dataset timestamp is newwer
+             * 
+             */
+            void updateLiveCache(const chaos::common::data::CDataWrapper*);
+
+            /**
+             * @brief update alive_cache if ts is newer
+             * 
+             */
+            void updateLiveCache(const std::string& name,int64_t te);
+
+
 
             /**
              * @brief remove storage data to from
diff --git a/ChaosMetadataService/QueryDataConsumer.cpp b/ChaosMetadataService/QueryDataConsumer.cpp
index 389b7e1b2a777da669e5014f76a1b45f8b71db74..d87b5b35d82edb588a8ffbd32f8af91d14661ab5 100644
--- a/ChaosMetadataService/QueryDataConsumer.cpp
+++ b/ChaosMetadataService/QueryDataConsumer.cpp
@@ -23,7 +23,6 @@
 #include "ChaosMetadataService.h"
 #include "persistence/persistence.h"
 #include "worker/DeviceSharedDataWorker.h"
-#define SKIP_OLDER_THAN 5*60000
 #if CHAOS_PROMETHEUS
 #include "worker/DeviceSharedDataWorkerMetricCollector.h"
 #endif
@@ -67,7 +66,11 @@ QueryDataConsumer::~QueryDataConsumer() {}
 void QueryDataConsumer::init(void* init_data) {
   //get new chaos direct io endpoint
   server_endpoint = NetworkBroker::getInstance()->getDirectIOServerEndpoint();
-  if (!server_endpoint) throw chaos::CException(-2, "Invalid server endpoint", __FUNCTION__);
+  if(server_endpoint==NULL){
+      INFO << "DirectIO disabled";
+      return;
+  }
+//  if (!server_endpoint) throw chaos::CException(-2, "Invalid server endpoint", __FUNCTION__);
   INFO << "QueryDataConsumer initialized with endpoint " << server_endpoint->getRouteIndex();
 
   INFO << "Allocating DirectIODeviceServerChannel";
@@ -120,20 +123,10 @@ int QueryDataConsumer::consumePutEvent(const std::string&                 key,
                                        const ChaosStringSetConstSPtr      meta_tag_set,
                                        chaos::common::data::CDataWrapper& data_pack) {
   int      err = 0;
-  uint64_t now = TimingUtil::getTimeStamp();
-  if (data_pack.hasKey(DataPackCommonKey::DPCK_HIGH_RESOLUTION_TIMESTAMP)) {
-    int32_t lat = TimingUtil::getTimeStampInMicroseconds() - data_pack.getInt64Value(DataPackCommonKey::DPCK_HIGH_RESOLUTION_TIMESTAMP);
-    data_pack.addInt32Value(DataPackCommonKey::NODE_MDS_TIMEDIFF, lat);
-  }
-  if((hst_tag==0) || (hst_tag==DataServiceNodeDefinitionType::DSStorageTypeLive)){
-    // if only live and there are packets older 5min skip
-    if(data_pack.hasKey(DataPackCommonKey::DPCK_TIMESTAMP)){
-      if((now-data_pack.getInt64Value(DataPackCommonKey::DPCK_TIMESTAMP))>SKIP_OLDER_THAN){
-        return 0;
-      }
-    }
-  }
-  data_pack.addInt64Value(NodeHealtDefinitionKey::NODE_HEALT_MDS_TIMESTAMP, now);
+
+
+  
+  //data_pack.addInt64Value(NodeHealtDefinitionKey::NODE_HEALT_MDS_TIMESTAMP, now);
   BufferSPtr channel_data_injected(data_pack.getBSONDataBuffer().release());
 
   DataServiceNodeDefinitionType::DSStorageType storage_type = static_cast<DataServiceNodeDefinitionType::DSStorageType>(hst_tag);
diff --git a/ChaosMetadataService/QueryDataMsgPSConsumer.cpp b/ChaosMetadataService/QueryDataMsgPSConsumer.cpp
index 138cdf41bca24c51ad42542cf5fc95400f763459..39e99de7900ec5ecbc3d6dd6acce97dd8ae7dc60 100644
--- a/ChaosMetadataService/QueryDataMsgPSConsumer.cpp
+++ b/ChaosMetadataService/QueryDataMsgPSConsumer.cpp
@@ -60,7 +60,7 @@ QueryDataMsgPSConsumer::QueryDataMsgPSConsumer(const std::string& id)
 
   cons = chaos::common::message::MessagePSDriver::getConsumerDriver(msgbrokerdrv, groupid);
 }
-void QueryDataMsgPSConsumer::messageHandler(const chaos::common::message::ele_t& data) {
+void QueryDataMsgPSConsumer::messageHandler( chaos::common::message::ele_t& data) {
   try {
   ChaosStringSetConstSPtr meta_tag_set;
 
@@ -75,38 +75,66 @@ void QueryDataMsgPSConsumer::messageHandler(const chaos::common::message::ele_t&
   //std::replace(kp.begin(), kp.end(), '.', '/');
   //DBG<<"data from:"<<kp<<" size:"<<data.cd->getBSONRawSize();
   if(data.cd->hasKey(DataPackCommonKey::DPCK_DATASET_TYPE)&&data.cd->hasKey(NodeDefinitionKey::NODE_UNIQUE_ID)){
+    uint64_t now = TimingUtil::getTimeStamp();
+
     int pktype=data.cd->getInt32Value(DataPackCommonKey::DPCK_DATASET_TYPE);
+    
+    int64_t ts=0;
+    uint32_t                st=(uint32_t)DataServiceNodeDefinitionType::DSStorageTypeLive;
+    if(data.cd->hasKey(DataServiceNodeDefinitionKey::DS_STORAGE_TYPE)){
+      st=data.cd->getInt32Value(DataServiceNodeDefinitionKey::DS_STORAGE_TYPE);
+      if(pktype!=DataPackCommonKey::DPCK_DATASET_TYPE_OUTPUT){
+          st|=(uint32_t)DataServiceNodeDefinitionType::DSStorageTypeLive;
+      }
+    }
+    
     kp=data.cd->getStringValue(NodeDefinitionKey::NODE_UNIQUE_ID)+datasetTypeToPostfix(pktype);
-     uint32_t                st=(uint32_t)DataServiceNodeDefinitionType::DSStorageTypeLive;
+    int32_t lat=0;
     if(pktype==DataPackCommonKey::DPCK_DATASET_TYPE_LOG){
-    //  DBG<<"Queue:"<<CObjectProcessingPriorityQueue<CDataWrapper>::queueSize()<<" LOG:"<<data.cd->getJSONString();
-      if(CObjectProcessingPriorityQueue<CDataWrapper>::queueSize()<MAX_LOG_QUEUE){
-        CObjectProcessingPriorityQueue<CDataWrapper>::push(data.cd,0);
-      } else {
-        ERR<<kp<<"] too many logs on queue for DB:"<<CObjectProcessingPriorityQueue<CDataWrapper>::queueSize();
-        return;
-      }
-
-    } else if(pktype==DataPackCommonKey::DPCK_DATASET_TYPE_HEALTH) {
-      uint64_t ts=0;
+        if(data.cd->hasKey(MetadataServerLoggingDefinitionKeyRPC::PARAM_NODE_LOGGING_LOG_TIMESTAMP)){
+          ts=data.cd->getInt64Value(MetadataServerLoggingDefinitionKeyRPC::PARAM_NODE_LOGGING_LOG_TIMESTAMP);
+          lat=now-ts;
+          if(lat>SKIP_OLDER_THAN){
+              ERR<<kp<<" log too old: "<<lat<< " ms, skipping...";
+              return ;
+          }
+          data.cd->addInt32Value(DataPackCommonKey::NODE_MDS_TIMEDIFF,lat );
 
-      if(data.cd->hasKey(DataPackCommonKey::DPCK_TIMESTAMP)){
-        ts=data.cd->getInt64Value(DataPackCommonKey::DPCK_TIMESTAMP);
-        if((TimingUtil::getTimeStamp()-ts)>(chaos::common::constants::HBTimersTimeoutinMSec*2)){
-          // skip healt too old
+        }
+    //  DBG<<"Queue:"<<CObjectProcessingPriorityQueue<CDataWrapper>::queueSize()<<" LOG:"<<data.cd->getJSONString();
+        if(CObjectProcessingPriorityQueue<CDataWrapper>::queueSize()<MAX_LOG_QUEUE){
+          CDWShrdPtr ptr(data.cd.release());
+          CObjectProcessingPriorityQueue<CDataWrapper>::push(ptr,0);
+        } else {
+          ERR<<kp<<"] too many logs on queue for DB:"<<CObjectProcessingPriorityQueue<CDataWrapper>::queueSize();
           return;
         }
+    } else if(data.cd->hasKey(DataPackCommonKey::DPCK_TIMESTAMP)){
+        ts=data.cd->getInt64Value(DataPackCommonKey::DPCK_TIMESTAMP);
+        lat=(now-ts);
+        data.cd->addInt32Value(DataPackCommonKey::NODE_MDS_TIMEDIFF,lat );
+        if((pktype==DataPackCommonKey::DPCK_DATASET_TYPE_HEALTH)){
+          if(lat>(chaos::common::constants::HBTimersTimeoutinMSec*2)){
+         // health too old
+            return;
+          }
+        } else if((pktype==DataPackCommonKey::DPCK_DATASET_TYPE_OUTPUT)||(pktype==DataPackCommonKey::DPCK_DATASET_TYPE_INPUT)){
+              if(((st==0) || (st==DataServiceNodeDefinitionType::DSStorageTypeLive))){
+              if(lat>SKIP_OLDER_THAN){
+                 ERR<<kp<<" too old: "<<lat<< " ms, skipping...";
+              // output too old
+                return;
+              }
+          data.cd->removeKey(DataServiceNodeDefinitionKey::DS_STORAGE_TYPE);
+          data.cd->removeKey(DataPackCommonKey::DPCK_DATASET_TYPE);
+          
+        } 
+       
+   
       }
-     // alive_map[kp]=TimingUtil::getTimeStamp();
-    } else {
-        st = data.cd->getInt32Value(DataServiceNodeDefinitionKey::DS_STORAGE_TYPE);
-        if(pktype!=DataPackCommonKey::DPCK_DATASET_TYPE_OUTPUT){
-          st|=(uint32_t)DataServiceNodeDefinitionType::DSStorageTypeLive;
-        }
-
     }
-    QueryDataConsumer::consumePutEvent(kp, (uint8_t)st, meta_tag_set, *(data.cd.get()));
     
+    QueryDataConsumer::consumePutEvent(kp, (uint8_t)st, meta_tag_set, *(data.cd.get()));
   }
   } catch(const chaos::CException& e ){
     ERR<<"Chaos Exception caught processing key:"<<data.key<<" ("<<data.off<<","<<data.par<<") error:"<<e.what();
@@ -123,7 +151,7 @@ void QueryDataMsgPSConsumer::messageHandler(const chaos::common::message::ele_t&
       
   }
 
-void QueryDataMsgPSConsumer::messageError(const chaos::common::message::ele_t& data) {
+void QueryDataMsgPSConsumer::messageError( chaos::common::message::ele_t& data) {
   ChaosStringSetConstSPtr meta_tag_set;
       boost::mutex::scoped_lock ll(map_m);
     std::string path=data.key;
@@ -180,14 +208,16 @@ while(attempt--){
   DBG <<"] Found " << nodes.size()<< " to subscribe";
 
   for(std::vector<std::string>::iterator i=nodes.begin();i!=nodes.end();i++){
-    DBG <<"] Subscribing to:" << *i;
+    if(i->size()){
+      DBG <<"] Subscribing to:" << *i;
 
-    if (cons->subscribe(*i) != 0) {
-        ERR <<" cannot subscribe to :" << *i<<" err:"<<cons->getLastError();
-                
-    } else {
-        DBG <<"] Subscribed to:" << *i;
-        
+      if (cons->subscribe(*i) != 0) {
+          ERR <<" cannot subscribe to :" << *i<<" err:"<<cons->getLastError();
+                  
+      } else {
+          DBG <<"] Subscribed to:" << *i;
+          
+      }
     }  
   }
 }
@@ -251,7 +281,7 @@ int QueryDataMsgPSConsumer::consumeHealthDataEvent(const std::string&
     }
   }*/
   if(channel_data.get()==NULL || channel_data->data()==NULL){
-    DBG<<"Empty health for:\""<<key<<"\" registration pack";
+   // DBG<<"Empty health for:\""<<key<<"\" registration pack";
     if(alive_map.find(key)==alive_map.end()){
         if (cons->subscribe(key) != 0) {
               ERR <<"] cannot subscribe to :" << key<<" err:"<<cons->getLastError();
diff --git a/ChaosMetadataService/QueryDataMsgPSConsumer.h b/ChaosMetadataService/QueryDataMsgPSConsumer.h
index ff9ce865ec093c3e2e6c78ab2c108318330094fa..d55708c70edd5992133ef2323719c0be76a7e5dc 100644
--- a/ChaosMetadataService/QueryDataMsgPSConsumer.h
+++ b/ChaosMetadataService/QueryDataMsgPSConsumer.h
@@ -28,6 +28,7 @@
 
 namespace chaos {
 namespace metadata_service {
+#define SKIP_OLDER_THAN 5*60000
 
 class QueryDataMsgPSConsumer : public QueryDataConsumer,protected chaos::common::pqueue::CObjectProcessingPriorityQueue<chaos::common::data::CDataWrapper>  {
   std::string                             msgbrokerdrv;
@@ -36,8 +37,8 @@ class QueryDataMsgPSConsumer : public QueryDataConsumer,protected chaos::common:
   static std::map<std::string, uint64_t>         alive_map;
   chaos::common::message::consumer_uptr_t cons;
   static boost::mutex                            map_m;
-  void                                    messageHandler(const chaos::common::message::ele_t& data);
-  void                                  messageError(const chaos::common::message::ele_t& data);
+  void                                    messageHandler( chaos::common::message::ele_t& data);
+  void                                  messageError( chaos::common::message::ele_t& data);
   int subscribe_retry;
   //---------------- DirectIODeviceServerChannelHandler -----------------------
   void processBufferElement(chaos::common::data::CDWShrdPtr log_entry);
diff --git a/ChaosMetadataService/common/CUCommonUtility.cpp b/ChaosMetadataService/common/CUCommonUtility.cpp
index 0be11bf256dd7bfc2d02b1bafca7bb9cf15a16c6..1402e8d284a18ce32a3e43b2217b6127f74f18d6 100644
--- a/ChaosMetadataService/common/CUCommonUtility.cpp
+++ b/ChaosMetadataService/common/CUCommonUtility.cpp
@@ -219,6 +219,7 @@ void CUCommonUtility::addDataServicePack(ChaosUniquePtr<chaos::common::data::CDa
   if (now >= nu_cache_ts ||
       data_services.size() == 0) {
     data_services.clear();
+    nu_cache_ts = now + chaos::common::constants::RefreshEndpointMSec;
 
     if ((err = ds_da->getBestNDataService(ha_zone_name,
                                           data_services,
@@ -226,7 +227,6 @@ void CUCommonUtility::addDataServicePack(ChaosUniquePtr<chaos::common::data::CDa
       throw CException(err, "Error fetching best available data service", __PRETTY_FUNCTION__);
     }
     //update cache on first call after ten seconds
-    nu_cache_ts = now + chaos::common::constants::RefreshEndpointMSec;
   }
   std::string msgbroker = GlobalConfiguration::getInstance()->getOption<std::string>(InitOption::OPT_MSG_BROKER_SERVER);
   if (msgbroker.size()) {
@@ -273,6 +273,7 @@ void CUCommonUtility::addDataServicePack(ChaosUniquePtr<chaos::common::data::CDa
   //result.reset(new CDataWrapper());
   if (data_services.size() == 0) {
     /// something wrong returning my self
+    
     result->appendStringToArray(boost::str(boost::format("%1%|0") % NetworkBroker::getInstance()->getDirectIOUrl()));
     result->finalizeArrayForKey(chaos::DataServiceNodeDefinitionKey::DS_DIRECT_IO_FULL_ADDRESS_LIST);
 
diff --git a/ChaosMetadataService/main.cpp b/ChaosMetadataService/main.cpp
index 904b40e9ac05b3707fdf6d356fa2061acd7e1ec2..f2321c108ceb7660397d09a93daf67ec18713950 100644
--- a/ChaosMetadataService/main.cpp
+++ b/ChaosMetadataService/main.cpp
@@ -119,6 +119,7 @@ int main(int argc, const char * argv[]) {
                                                                                                          "Specify the check time (in seconds ) for ageing management (default is one day of delay)",
                                                                                                          86400,
                                                                                                          &ChaosMetadataService::getInstance()->setting.cron_job_ageing_management_repeat_time);
+
         ChaosMetadataService::getInstance()->init(argc, argv);
         
         ChaosMetadataService::getInstance()->start();
diff --git a/ChaosMetadataService/mds_constants.h b/ChaosMetadataService/mds_constants.h
index 1d12d9625d60fe57c97ce37a9f7e191b3e0d1a29..47c2caf1500a15725a094821b914667d6b77f3bd 100644
--- a/ChaosMetadataService/mds_constants.h
+++ b/ChaosMetadataService/mds_constants.h
@@ -20,6 +20,7 @@ static const char* OPT_CRON_JOB_AGEING_MANAGEMENT  ="cron-job-ageing-management-
 static const char* OPT_ARCHIVER_NUM                        ="archiver-instances";
 static const char* OPT_ARCHIVER_THREAD                     ="archiver-thread";
 static const char* OPT_ARCHIVER_QUEUE_PUSH_TIMEOUT         ="archiver-queue-push-timeout";
+
     }
 }
 #endif
diff --git a/ChaosMetadataService/object_storage/influxDB/InfluxDB.cpp b/ChaosMetadataService/object_storage/influxDB/InfluxDB.cpp
index dfe938adfce40b44e30389540c7ab4a435bc3d33..9a0aaebc4fb5893d852f486b99b0cc76ef0fbe73 100644
--- a/ChaosMetadataService/object_storage/influxDB/InfluxDB.cpp
+++ b/ChaosMetadataService/object_storage/influxDB/InfluxDB.cpp
@@ -82,6 +82,10 @@ inline bool skipDefault(const std::string& name){
   if(name==chaos::DataPackCommonKey::DPCK_DEVICE_ID) return true;
   if(name==chaos::DataServiceNodeDefinitionKey::DS_STORAGE_TYPE) return true;
   if(name==chaos::DataPackCommonKey::NODE_MDS_TIMEDIFF) return true;
+  if(name==chaos::ControlUnitDatapackCommonKey::RUN_ID) return true;
+  if(name==chaos::DataPackCommonKey::DPCK_DEVICE_ID) return true;  
+  if(name==chaos::NodeHealtDefinitionKey::NODE_HEALT_MDS_TIMESTAMP) return true;
+
 
 
 return false;
diff --git a/ChaosMetadataService/object_storage/posixFile/PosixFile.cpp b/ChaosMetadataService/object_storage/posixFile/PosixFile.cpp
index c9ef6b3cd78ae62242ca1264275ee800e0bb71cb..cae3bcee0e3da124edd94443dca28c11cbaa8f23 100644
--- a/ChaosMetadataService/object_storage/posixFile/PosixFile.cpp
+++ b/ChaosMetadataService/object_storage/posixFile/PosixFile.cpp
@@ -56,7 +56,7 @@ chaos::common::metric::CounterUniquePtr PosixFile::counter_read_data_uptr;
 chaos::common::metric::GaugeUniquePtr   PosixFile::gauge_insert_time_uptr;
 chaos::common::metric::GaugeUniquePtr   PosixFile::gauge_query_time_uptr;
 #endif
-boost::lockfree::queue<PosixFile::dirpath_t*, boost::lockfree::fixed_sized<true> > PosixFile::file_to_finalize(MAXDIROPENED);
+//boost::lockfree::queue<PosixFile::dirpath_t*, boost::lockfree::fixed_sized<true> > PosixFile::file_to_finalize(MAXDIROPENED);
 #ifdef CERN_ROOT
 GenerateRootJob PosixFile::rootGenJob;
 #endif
@@ -555,7 +555,7 @@ PosixFile::PosixFile(const std::string& name)
 
 #endif
   DBG << " BASED DIR:" << name;
-  AsyncCentralManager::getInstance()->addTimer(this, 2000, 2000);
+ // AsyncCentralManager::getInstance()->addTimer(this, 2000, 2000);
   finalize_th = boost::thread(&PosixFile::finalizeJob, this);
 #ifdef CERN_ROOT
   rootGenJob.init(1);
@@ -566,25 +566,9 @@ void PosixFile::finalizeJob() {
 
   exitFinalizeJob = false;
   do {
-    boost::mutex::scoped_lock lock(mutex_io);
-
-    wait_data.wait(lock);
-    dirpath_t* ele;
-
-    while (file_to_finalize.pop(ele)) {
-      DBG << "processing dir :" << ele->dir << " name:" << ele->name;
-      if (createFinal(ele->dir, ele->name, true) >= 0) {
-      // DBG << " CREATE FINAL: " << fpath;
-#ifdef CERN_ROOT
-        if (PosixFile::generateRoot) {
-          std::string                                                     fpath = ele->dir + "/" + ele->name + ((PosixFile::compress) ? ".lz4" : "");
-          chaos::CObjectProcessingQueue<std::string>::QueueElementShrdPtr a(new std::string(fpath));
-          rootGenJob.push(a);
-        }
-#endif
-
-        delete ele;
-      }
+    
+    if(!process_dirs()){
+      sleep(PROCESS_DIR_FREQ_SEC);
     }
 
   } while (!exitFinalizeJob);
@@ -594,7 +578,7 @@ void PosixFile::finalizeJob() {
 PosixFile::~PosixFile() {
   exitFinalizeJob = true;
 
-  AsyncCentralManager::getInstance()->removeTimer(this);
+ // AsyncCentralManager::getInstance()->removeTimer(this);
 #ifdef CERN_ROOT
   rootGenJob.deinit();
 #endif
@@ -1419,8 +1403,8 @@ int PosixFile::getObjectByIndex(const chaos::common::data::CDWShrdPtr& index,
   return 0;
 }
 
-void PosixFile::timeout() {
-
+bool PosixFile::process_dirs() {
+  bool work_done=false;
   // remove directory write cache
   for (write_path_t::iterator id = s_lastWriteDir.begin(); id != s_lastWriteDir.end(); ) {
     uint64_t ts = chaos::common::utility::TimingUtil::getTimeStamp();
@@ -1450,19 +1434,21 @@ void PosixFile::timeout() {
       }
       int ret;
       if ((ret = makeOrdered(id->second)) > 0) {
-        dirpath_t* ele = new dirpath_t();
-        ele->dir       = dstdir;
-        ele->name      = POSIX_FINAL_DATA_NAME;
-        DBG << "TO Process" << dstdir;
-
-        file_to_finalize.push(ele);
-        wait_data.notify_all();
+        
+        DBG << "processing dir :" << dstdir << " name:" << POSIX_FINAL_DATA_NAME;
+        if (createFinal(dstdir, POSIX_FINAL_DATA_NAME, true) >= 0) {
+        // DBG << " CREATE FINAL: " << fpath;
+      #ifdef CERN_ROOT
+              if (PosixFile::generateRoot) {
+                std::string                                                     fpath = ele->dir + "/" + ele->name + ((PosixFile::compress) ? ".lz4" : "");
+                chaos::CObjectProcessingQueue<std::string>::QueueElementShrdPtr a(new std::string(fpath));
+                rootGenJob.push(a);
+              }
+      #endif
 
-        /*if (createFinal(dstdir, POSIX_FINAL_DATA_NAME) >= 0) {
+        }
+        work_done=true;
 
-          DBG << " CREATE FINAL: " <<dstdir + "/"+POSIX_FINAL_DATA_NAME;
-          
-        }*/
       } else if (ret < 0) {
         DBG << "remove resource:" << dstdir;
 
@@ -1504,6 +1490,7 @@ void PosixFile::timeout() {
       id++;
     }
   }*/
+  return work_done;
 }
 
 //!return the number of object for a determinated key that are store for a time range
diff --git a/ChaosMetadataService/object_storage/posixFile/PosixFile.h b/ChaosMetadataService/object_storage/posixFile/PosixFile.h
index 546ae867f2a4fc5a81cb03e1df53142eed02d19e..96947f7325809e33a395a8ea93356e41494f001f 100644
--- a/ChaosMetadataService/object_storage/posixFile/PosixFile.h
+++ b/ChaosMetadataService/object_storage/posixFile/PosixFile.h
@@ -38,6 +38,7 @@
 #endif //CHAOS_PROMETHEUS
 // 3Khz
 #define MAX_NUM_OF_FILE_PER_MINUTE 60*3000
+#define PROCESS_DIR_FREQ_SEC 2
 #include "FileLock.h"
 
 namespace chaos {
@@ -165,7 +166,7 @@ namespace chaos {
                     int getData(abstraction::VectorObject& data,int maxData,const uint64_t timestamp_from,const uint64_t timestamp_to,chaos::common::direct_io::channel::opcode_headers::SearchSequence&,int timeout=5000);
                     ~SearchWorker();
             };
-            class PosixFile:public metadata_service::object_storage::abstraction::ObjectStorageDataAccess,public chaos::common::async_central::TimerHandler {
+            class PosixFile:public metadata_service::object_storage::abstraction::ObjectStorageDataAccess{
 
 
                     friend  SearchWorker;
@@ -235,8 +236,8 @@ public:
                 typedef std::map<std::string,read_path_t> cacheRead_t; 
                 static boost::mutex last_access_mutex,cache_mutex;
                 static cacheRead_t s_lastAccessedDir;
-                // return number of items, or negative if error
-                void timeout();
+                // something to process
+                bool process_dirs();
            #ifdef CERN_ROOT
      
                 
@@ -256,7 +257,7 @@ public:
                 boost::thread finalize_th;
                 boost::condition_variable wait_data;
                 boost::mutex mutex_io;
-                static boost::lockfree::queue<dirpath_t*, boost::lockfree::fixed_sized<true> > file_to_finalize; 
+             //   static boost::lockfree::queue<dirpath_t*, boost::lockfree::fixed_sized<true> > file_to_finalize; 
 
                 bool exitFinalizeJob;
 
diff --git a/ChaosMetadataService/object_storage/posixFile/PosixFileObjectStorageDriver.cpp b/ChaosMetadataService/object_storage/posixFile/PosixFileObjectStorageDriver.cpp
index 51126762dd5e26d758749118e191d0540a318e06..b2f1dccdac2432f5b670fb36e79c020db2ed2fcf 100644
--- a/ChaosMetadataService/object_storage/posixFile/PosixFileObjectStorageDriver.cpp
+++ b/ChaosMetadataService/object_storage/posixFile/PosixFileObjectStorageDriver.cpp
@@ -92,12 +92,23 @@ void PosixFileObjectStorageDriver::init(void *init_data) throw (chaos::CExceptio
     const std::string database = ChaosMetadataService::getInstance()->setting.fsobject_storage_setting.key_value_custom_param["db"];
     MapKVP& obj_stoarge_kvp = metadata_service::ChaosMetadataService::getInstance()->setting.fsobject_storage_setting.key_value_custom_param;
   */
-  if ((boost::filesystem::exists(basedatapath) == false) &&
-            (boost::filesystem::create_directories(basedatapath) == false)) {
-         ERR<<"cannot create directory:"<<basedatapath;
-        throw chaos::CException(-1,__PRETTY_FUNCTION__,"cannot create directory:"+basedatapath);
+  
+    if ((boost::filesystem::exists(basedatapath) == false)){
+        bool ret=false;
+        try {
+            ret=boost::filesystem::create_directories(basedatapath);
+        }  catch(boost::filesystem::filesystem_error& e){
+            throw chaos::CException(-1,__PRETTY_FUNCTION__,"cannot create directory:"+basedatapath+ " err:"+e.what());
+        }
+          if( ret == false) {
+            ERR<<"cannot create directory:"<<basedatapath;
+            throw chaos::CException(-2,__PRETTY_FUNCTION__,"cannot create directory:"+basedatapath);
+
+            }
+    }
+    
+        
 
-  }
     PosixFile::removeTemp=removeTemp;
     PosixFile::generateRoot=genroot;
     PosixFile::compress=compressed;
diff --git a/ChaosMetadataService/persistence/mongodb/MongoDBSnapshotDataAccess.cpp b/ChaosMetadataService/persistence/mongodb/MongoDBSnapshotDataAccess.cpp
index 5c13ac05259e07574e47dde90098578d71378c2f..4b37b05484d0e8a038004bd9f1528323014b0004 100644
--- a/ChaosMetadataService/persistence/mongodb/MongoDBSnapshotDataAccess.cpp
+++ b/ChaosMetadataService/persistence/mongodb/MongoDBSnapshotDataAccess.cpp
@@ -79,8 +79,16 @@ int MongoDBSnapshotDataAccess::snapshotCreateNewWithName(const std::string& snap
                                       check_unique_q))) {//check existence
             MDBDSDA_ERR << CHAOS_FORMAT("Error %1% checking existence snapshot %2%", %err%snapshot_name);
         } else if(check_result.isEmpty() == false) {//if false means that a document has been found
-            MDBDSDA_ERR << CHAOS_FORMAT("A snapshot for name %1% already exists", %snapshot_name);
-            err = -1;
+            MDBDSDA_DBG << CHAOS_FORMAT("A snapshot for name %1% already exists, updating ", %snapshot_name);
+
+            if((err = connection->update(MONGO_DB_COLLECTION_NAME(MONGO_DB_COLLECTION_SNAPSHOT),
+                                     check_unique_q,
+                                     q,
+                                     true,
+                                     false,
+                                     &mongo::WriteConcern::acknowledged))) {
+                MDBDSDA_ERR << CHAOS_FORMAT("Error %1% updating snapshot %w%", %err%snapshot_name);
+            }
         } else if((err = connection->insert(MONGO_DB_COLLECTION_NAME(MONGO_DB_COLLECTION_SNAPSHOT), q))) {//we can proceeed to insert the new snapshot
             MDBDSDA_ERR << CHAOS_FORMAT("Error %1% creating snapshot %2%", %err%snapshot_name);
         }
diff --git a/chaos/common/CMakeLists.txt b/chaos/common/CMakeLists.txt
index f7c93e34557c0c329b25e96dfe937d1b768ce708..b5a7842eee04c0d33d89be1dd9f3239ebe81b9c7 100644
--- a/chaos/common/CMakeLists.txt
+++ b/chaos/common/CMakeLists.txt
@@ -496,7 +496,10 @@ SET(common_lib_src ${common_lib_src}
                     rpc/RpcClient.cpp
                     rpc/RpcServer.cpp
                     rpc/zmq/ZMQClient.cpp
-                    rpc/zmq/ZMQServer.cpp)
+                    rpc/zmq/ZMQServer.cpp
+                    rpc/psm/PSMClient.cpp
+                    rpc/psm/PSMServer.cpp
+                    )
 SET(common_lib_src ${common_lib_src}
                     utility/NamedService.cpp
                     utility/StartableService.cpp
diff --git a/chaos/common/ChaosCommon.cpp b/chaos/common/ChaosCommon.cpp
index ea4f339580471179701ed60502d5c57c9c93fcd3..8f050a3928bc0fcefb9972a699dac0645d9c3a08 100644
--- a/chaos/common/ChaosCommon.cpp
+++ b/chaos/common/ChaosCommon.cpp
@@ -287,7 +287,11 @@ void ChaosAbstractCommon::init(void *init_data) {
             //initialize the plugin manager
             chaos::common::utility::InizializableService::initImplementation(chaos::common::plugin::PluginManager::getInstance(), NULL, "PluginManager", __PRETTY_FUNCTION__);
         }
-        
+         if (GlobalConfiguration::getInstance()->hasOption(InitOption::OPT_NODEUID)) {
+             nodeuid=GlobalConfiguration::getInstance()->getConfiguration()->getStringValue(InitOption::OPT_NODEUID);
+         } else {
+             nodeuid=NetworkBroker::getInstance()->getRPCUrl();
+         }
         //finally we can register the system rpc api for common uses
         AbstActionDescShrPtr
         action_description = addActionDescritionInstance<ChaosAbstractCommon>(this,
diff --git a/chaos/common/ChaosCommon.h b/chaos/common/ChaosCommon.h
index e4c6a0221d8703d71c2c6181e852766d838dc46e..f00a20f3c26fc5641f8d8191f7d23363bdc0ca19 100644
--- a/chaos/common/ChaosCommon.h
+++ b/chaos/common/ChaosCommon.h
@@ -67,6 +67,8 @@ namespace chaos {
         chaos::common::data::CDWUniquePtr _registrationAck(chaos::common::data::CDWUniquePtr data);
 
     public:
+    
+        std::string nodeuid;
         //! Constructor Method
         /*!
          This method call the \ref GlobalConfiguration::preParseStartupParameters method, starting the
diff --git a/chaos/common/additional_lib/HttpPost.cpp b/chaos/common/additional_lib/HttpPost.cpp
index 56105c1009f731550430307c59f2d0551d84c37d..e2d445439069a74173148e6c7e472142a86336a7 100644
--- a/chaos/common/additional_lib/HttpPost.cpp
+++ b/chaos/common/additional_lib/HttpPost.cpp
@@ -1,98 +1,118 @@
 #include "HttpPost.h"
-#include "mongoose.h"
 #include <chaos/common/global.h>
+#include <chaos/common/utility/TimingUtil.h>
+#include "mongoose.h"
+#define DBG LDBG_ << "[" << __PRETTY_FUNCTION__ << "] "
+#define ERR LERR_ << "## [" << __PRETTY_FUNCTION__ << "] "
 
+namespace chaos {
+namespace common {
+namespace http {
+static int s_exit_flag = 0, counter = 0;
+//     static std::stringstream bufres;
 
-namespace chaos{
-    namespace common{
-        namespace http{
-        static int s_exit_flag = 0;
-   //     static std::stringstream bufres;
-
-            static void ev_handler(struct mg_connection *nc, int ev, void *ev_data)
-{
+static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
   struct http_message *hm = (struct http_message *)ev_data;
-  int connect_status;
-
-  switch (ev)
-  {
-  case MG_EV_CONNECT:
-    connect_status = *(int *)ev_data;
-    if (connect_status != 0)
-    {
-      // printf("Error connecting to %s: %s\n", hm->uri, strerror(connect_status));
-      s_exit_flag = -1;
-    }
-    break;
-  case MG_EV_HTTP_REPLY:{
-    std::stringstream *ptr= (std::stringstream *)nc->mgr->user_data;
-  //  LDBG_<<"Got reply:"<< hm->body.len<<" resp:"<< hm->body.p,hm->resp_code;
-    if(ptr&&hm->body.p && hm->body.len){
-        ptr->write((char*)hm->body.p,hm->body.len);
-        //LDBG_<<hm->body.len<<"] Read:"<<(char*)hm->body.p;
-
-       // LDBG_<<"Read:"<<ptr->str();
+  int                  connect_status;
+
+  switch (ev) {
+    case MG_EV_CONNECT:
+      connect_status = *(int *)ev_data;
+      if (connect_status != 0) {
+          s_exit_flag = -1;
+          DBG << "connect status:" << connect_status<<" error:"<<strerror(connect_status)<<" exit:"<<s_exit_flag;
+
+      }
+      break;
+    case MG_EV_HTTP_REPLY: {
+      std::stringstream *ptr = (std::stringstream *)nc->mgr->user_data;
+      //  LDBG_<<"Got reply:"<< hm->body.len<<" resp:"<< hm->body.p,hm->resp_code;
+    //  DBG<<"REPLY hm:"<<hm<<" len:"<<hm->body.len;
+      if (ptr && hm && hm->body.p && hm->body.len) {
+        ptr->write((char *)hm->body.p, hm->body.len);
+        // LDBG_<<hm->body.len<<"] Read:"<<(char*)hm->body.p;
+
+        // LDBG_<<"Read:"<<ptr->str();
+      }
+      // printf("Got reply:\n%.*s\n%d\n", (int) hm->body.len, hm->body.p,hm->resp_code);
+
+      nc->flags |= MG_F_SEND_AND_CLOSE;
+      s_exit_flag = hm->resp_code;
+      break;
     }
-    // printf("Got reply:\n%.*s\n%d\n", (int) hm->body.len, hm->body.p,hm->resp_code);
-    
-    nc->flags |= MG_F_SEND_AND_CLOSE;
-    s_exit_flag = hm->resp_code;
-    break;
+    case MG_EV_CLOSE:
+     // DBG<<"CLOSE:"<<s_exit_flag;
+      if (s_exit_flag == 0) {
+        s_exit_flag = 1;
+
+        //    printf("Server closed connection\n");
+      };
+      break;
+    default:
+    //  ERR << "MONGOOSE DEFAULT:" << s_exit_flag << " EV:" << ev << " counter:" << counter;
+      break;
   }
-  case MG_EV_CLOSE:
-    if (s_exit_flag == 0)
-    {
-                 s_exit_flag = 1;
+}
+HttpPost::HttpPost(const std::string &id, uint32_t timeout_ms, uint32_t _retry_offline_ms)
+    : clientid(id), mgr(NULL), timeo(timeout_ms), retry_offline_ms(_retry_offline_ms) {
+  mgr = (void *)calloc(1, sizeof(struct mg_mgr));
+}
+HttpPost::~HttpPost() {
+  free(mgr);
+}
+static boost::mutex devio_mutex;
+
+int HttpPost::post(const std::string &server, const std::string &api, const std::string &body, std::stringstream &res) {
+  char s_url[256];
+  int  ret;
+ // DBG << "before mutex offline:" << off_line.size();
 
-      //    printf("Server closed connection\n");
-    };
+  boost::lock_guard<boost::mutex> l(devio_mutex);
+ if (off_line.count(server) && (chaos::common::utility::TimingUtil::getTimeStamp() - off_line[server]) < retry_offline_ms) {
+    ERR << "server " << server << " has put offline for " << (retry_offline_ms - (chaos::common::utility::TimingUtil::getTimeStamp() - off_line[server])) << " ms";
 
-    break;
-  default:
-    break;
+    return 503;  // SERVICE UNAVAILABLE
   }
-}
-            HttpPost::HttpPost(const std::string& id,uint32_t timeout_ms):clientid(id),mgr(NULL),counter(0),timeo(timeout_ms){
-                mgr=(void*)calloc(1,sizeof(struct mg_mgr));
-            }   
-            HttpPost::~HttpPost(){
-                free(mgr);
-            }
-            static boost::mutex devio_mutex;
-
-
-            int HttpPost::post(const std::string& server,const std::string&api,const std::string& body,std::stringstream& res){
-              
-                char s_url[256];
-                int ret;
-                boost::mutex::scoped_lock l(devio_mutex);
-                mg_mgr_init((struct mg_mgr*)mgr,(void*)&res);
-
-                snprintf(s_url, sizeof(s_url), "%s/%s", server.c_str(), api.c_str());
-               // struct mg_connection *nc;
-                struct mg_mgr* p=(struct mg_mgr*)mgr;
-                s_exit_flag = 0;
-                counter=0;
-               // LDBG_<<"Connecting to:"<<s_url<<" body:"<<body;
-                mg_connect_http(p, ev_handler, s_url, "Content-Type:application/json\r\n", body.c_str());
-                while ((s_exit_flag == 0)&&(counter<timeo)){
-                    mg_mgr_poll(p, 1);
-                    counter++;
-                }
-                
-                if(counter==timeo){
-                  LERR_<<"Timeout of:"<<timeo;
-
-                  return 408; // REQUEST TIMEOUT
-                }
-
-               // LDBG_<<"exit:"<<s_exit_flag<<" body:"<<res.str();
-
-                return (s_exit_flag==-1)?599:s_exit_flag; // if -1 NETWORK_CONNECT_TIMEOUT_ERR
-            }
-
-
-            
-        }
+ 
+  mg_mgr_init((struct mg_mgr *)mgr, (void *)&res);
+
+  snprintf(s_url, sizeof(s_url), "%s/%s", server.c_str(), api.c_str());
+  // struct mg_connection *nc;
+  struct mg_mgr *p = (struct mg_mgr *)mgr;
+  s_exit_flag      = 0;
+  counter          = 0;
+  // LDBG_<<"Connecting to:"<<s_url<<" body:"<<body;
+ // DBG << "connecting " << s_url;
+
+  mg_connect_http(p, ev_handler, s_url, "Content-Type:application/json\r\n", body.c_str());
+  while ((s_exit_flag == 0) && (counter < timeo)) {
+    mg_mgr_poll(p, 1);
+    counter++;
+  }
+
+  //DBG << "exit polling " << s_exit_flag << " counter:" << counter;
+
+  if (counter == timeo) {
+    off_line[server] = chaos::common::utility::TimingUtil::getTimeStamp();
+    ERR << server << " timeout of:" << timeo << " at:" << off_line[server] << " put offline for:" << retry_offline_ms << " ms";
+
+    return 504;  // REQUEST GATEWAY TIMEOUT
+  }
+
+  // LDBG_<<"exit:"<<s_exit_flag<<" body:"<<res.str();
+  if (s_exit_flag == 200) {
+    if (off_line.erase(server)) {
+      DBG << "server " << server << " is online";
     }
+  } else if (s_exit_flag == -1) {
+    off_line[server] = chaos::common::utility::TimingUtil::getTimeStamp();
+    ERR << "server " << server << " connection error at:" << off_line[server] << " put offline for:" << retry_offline_ms << " ms";
+
+    return 502;
+  }
+  return s_exit_flag;
 }
+
+}  // namespace http
+}  // namespace common
+}  // namespace chaos
diff --git a/chaos/common/additional_lib/HttpPost.h b/chaos/common/additional_lib/HttpPost.h
index 2fe13e17690c1496f2da45b06ad8753ecb996f92..7ee21a160ef43052edb62199a56da7488526f12b 100644
--- a/chaos/common/additional_lib/HttpPost.h
+++ b/chaos/common/additional_lib/HttpPost.h
@@ -3,6 +3,7 @@
 #include <string>
 #include <sstream>
 #include <stdint.h>
+#include <map>
 namespace chaos{
     namespace common{
         namespace http{
@@ -10,9 +11,10 @@ namespace chaos{
                 std::string clientid;
                 void *mgr;
                 const uint32_t timeo;
-                int counter;
+                std::map<std::string,uint64_t> off_line;
+                const uint32_t retry_offline_ms;
                 public:
-                HttpPost(const std::string& id="Chaos HttpPost",uint32_t timeout_ms=2000);
+                HttpPost(const std::string& id="Chaos HttpPost",uint32_t timeout_ms=500,uint32_t _retry_offline_ms=10000);
                 ~HttpPost();
 
                 /**
diff --git a/chaos/common/caching_system/CacheDriver.cpp b/chaos/common/caching_system/CacheDriver.cpp
index f5da770bb77a997587340403855d59b72d4f33e3..2108baf6e9b73d0d55bafeb39d4176b0fce731c2 100644
--- a/chaos/common/caching_system/CacheDriver.cpp
+++ b/chaos/common/caching_system/CacheDriver.cpp
@@ -20,57 +20,125 @@
  */
 #include "CacheDriver.h"
 #include <chaos/common/data/CDataWrapper.h>
+#include <chaos/common/global.h>
+#include <chaos/common/utility/TimingUtil.h>
 using namespace chaos::common::cache_system;
 
-CacheDriver::CacheDriver(std::string alias):
-NamedService(alias){}
+CacheDriver::CacheDriver(std::string alias)
+    : NamedService(alias) {
+  enable_cache_for_ms.clear();
+  first_level_cache.clear();
+}
 
 CacheDriver::~CacheDriver() {}
 
+std::map<std::string, std::pair<int64_t, chaos::common::data::CDWShrdPtr> > CacheDriver::first_level_cache;
+std::map<std::string, int32_t>                                              CacheDriver::enable_cache_for_ms;
 //! init
 /*!
  Need a point to a structure DBDriverSetting for the setting
  */
-void CacheDriver::init(void *init_data)  {
-	if(init_data!=NULL){
-			cache_settings = *static_cast<CacheDriverSetting*>(init_data);
-	}
+void CacheDriver::init(void* init_data) {
+  if (init_data != NULL) {
+    cache_settings = *static_cast<CacheDriverSetting*>(init_data);
+  }
+  enable_cache_for_ms.clear();
+  first_level_cache.clear();
 }
 
 //! deinit
-void CacheDriver::deinit()  {}
-chaos::common::data::CDWShrdPtr CacheDriver::getData(const std::string& key){
-	CacheData d;
-	chaos::common::data::CDWShrdPtr ret;
-    if(getData(key,d)==0){
-      if(d.get()&&d->size()){
-        chaos::common::data::CDataWrapper* tmp = new chaos::common::data::CDataWrapper(d->data(),d->size());
-        ret.reset(tmp);
-        return ret;
+void CacheDriver::deinit() {
+  enable_cache_for_ms.clear();
+  first_level_cache.clear();
+}
+chaos::common::data::CDWShrdPtr CacheDriver::getData(const std::string& key) {
+  if ((enable_cache_for_ms.count(key)) && (first_level_cache.count(key))) {
+    uint64_t now = chaos::common::utility::TimingUtil::getTimeStamp();
+    if ((now - first_level_cache[key].first) < enable_cache_for_ms[key]) {
+      //  LDBG_ << "retrive from caching:" << key;
+
+      return first_level_cache[key].second;
+    }
+  }
+  CacheData                       d;
+  chaos::common::data::CDWShrdPtr ret;
+  if (getData(key, d) == 0) {
+    if (d.get() && d->size()) {
+      chaos::common::data::CDataWrapper* tmp = new chaos::common::data::CDataWrapper(d->data(), d->size());
+      ret.reset(tmp);
+      if (enable_cache_for_ms.count(key)) {
+        uint64_t now = chaos::common::utility::TimingUtil::getTimeStamp();
+        // LDBG_ << "mupdate caching:" << key;
+        first_level_cache[key] = {now, ret};
       }
     }
-	return ret;
+  }
+  return ret;
 }
-std::vector<chaos::common::data::CDWShrdPtr> CacheDriver::getData(const ChaosStringVector&    keys){
-	std::vector<chaos::common::data::CDWShrdPtr> ret;
-	 MultiCacheData            multi_cached_data;
-	 if(getData(keys,multi_cached_data)==0){
-		  for(ChaosStringVectorConstIterator it = keys.begin(),
-            end = keys.end();
-            it != end;
-            it++) {
-            const CacheData& cached_element = multi_cached_data[*it];
-			if((cached_element.get()==NULL) || (cached_element->size() == 0)){
-                ret.push_back(chaos::common::data::CDWShrdPtr());
-            } else {
-                chaos::common::data::CDWShrdPtr r =chaos::common::data::CDWShrdPtr(new chaos::common::data::CDataWrapper(cached_element->data(),cached_element->size()));
-                ret.push_back(r);
+void CacheDriver::enableCache(const std::string& key, int32_t validity_ms) {
+  if (validity_ms > 0) {
+    enable_cache_for_ms[key] = validity_ms;
+    LDBG_ << "enabling caching for key:" << key << " validity:" << validity_ms << " ms";
 
+  } else {
+    LDBG_ << "disabling caching for key:" << key;
+    enable_cache_for_ms.erase(key);
+  }
+}
 
-            }
+std::vector<chaos::common::data::CDWShrdPtr> CacheDriver::getData(const ChaosStringVector& keys) {
+  std::vector<chaos::common::data::CDWShrdPtr> ret;
+  MultiCacheData                               multi_cached_data;
+  std::map<std::string, bool>                  is_cached;
+  uint64_t                                     now = chaos::common::utility::TimingUtil::getTimeStamp();
+
+  int res = 0;
+  if (enable_cache_for_ms.size() == 0) {
+    res = getData(keys, multi_cached_data);
+  } else {
+    ChaosStringVector nocached;
+    for (ChaosStringVector::const_iterator i = keys.begin(); i != keys.end(); i++) {
+      if ((enable_cache_for_ms.count(*i)) && (first_level_cache.count(*i))) {
+        if ((now - first_level_cache[*i].first) < enable_cache_for_ms[*i]) {
+          is_cached[*i] = true;
+        } else {
+          nocached.push_back(*i);
+          is_cached[*i] = false;
         }
-     
+      } else {
+        nocached.push_back(*i);
+        is_cached[*i] = false;
+      }
     }
-	return ret;
+    res = getData(nocached, multi_cached_data);
+  }
+  if (res == 0) {
+    for (ChaosStringVectorConstIterator it  = keys.begin(),
+                                        end = keys.end();
+         it != end;
+         it++) {
+      if (((is_cached.size() == 0) || (is_cached[*it] == false))) {
+        const CacheData& cached_element = multi_cached_data[*it];
+        if ((cached_element.get() == NULL) || (cached_element->size() == 0)) {
+          ret.push_back(chaos::common::data::CDWShrdPtr());
+        } else {
+          chaos::common::data::CDWShrdPtr r = chaos::common::data::CDWShrdPtr(new chaos::common::data::CDataWrapper(cached_element->data(), cached_element->size()));
+          ret.push_back(r);
+          if (enable_cache_for_ms.count(*it)) {
+            if (enable_cache_for_ms[*it] > 0) {
+              //       LDBG_ << "mupdate caching:" << *it;
+              first_level_cache[*it] = {now, r};
+            }
+          }
+        }
+      } else {
+        //    LDBG_ << "mretrive from caching:" << *it;
 
+        ret.push_back(first_level_cache[*it].second);
+      }
+    }
+  } else {
+    LERR_ << __PRETTY_FUNCTION__ << " Error getting data from cache, ret:" << res;
+  }
+  return ret;
 }
\ No newline at end of file
diff --git a/chaos/common/caching_system/CacheDriver.h b/chaos/common/caching_system/CacheDriver.h
index 1c34a92d425b82e55b0a6a491e508072560f5bde..bdd65d6189a66c746b09ee4f76c7981448eb251b 100644
--- a/chaos/common/caching_system/CacheDriver.h
+++ b/chaos/common/caching_system/CacheDriver.h
@@ -54,7 +54,15 @@ namespace chaos {
 				CacheDriver(std::string alias);
             public:
                 CacheDriverSetting cache_settings;
-
+                static std::map<std::string,std::pair<int64_t,chaos::common::data::CDWShrdPtr> > first_level_cache;
+                static std::map<std::string,int32_t> enable_cache_for_ms;
+                /**
+                 * @brief enable cache for key
+                 * 
+                 * 
+                 * @param validity_ms =0 means disable
+                 */
+                void enableCache(const std::string&key,int32_t validity_ms);
 				virtual ~CacheDriver();
 				
                 virtual int putData(const std::string& key,
diff --git a/chaos/common/chaos_constants.h b/chaos/common/chaos_constants.h
index 67a627344b0a23996282d4b24b46a3749e1d65cd..c60b3ad8bd2eac67c009523bda6d2993d02d6efb 100644
--- a/chaos/common/chaos_constants.h
+++ b/chaos/common/chaos_constants.h
@@ -113,11 +113,10 @@ static const char* const OPT_SCRIPT_VM_KV_PARAM = "script-vm-kvp";
 static const char* const OPT_REST_POLL_TIME_US = "rest-poll-us";
 //!data directory for storage and checkpoint of nodes
 static const char* const OPT_DATA_DIR = "data-dir";
-#if defined(KAFKA_RDK_ENABLE) || defined(KAFKA_ASIO_ENABLE)
+
 static const char* const OPT_MSG_PRODUCER_KVP = "msgopt-producer-kvp";
 static const char* const OPT_MSG_CONSUMER_KVP = "msgopt-consumer-kvp";
 
-#endif
 
 #if CHAOS_PROMETHEUS
 //! config file parameter
@@ -132,7 +131,8 @@ static const char* const OPT_MSG_BROKER_SERVER = "msg-broker-server";
 static const char* const OPT_MSG_BROKER_DRIVER = "msg-broker-driver";
 
 static const char* const OPT_HA_ZONE_NAME                  = "ha-zone-name";
-static const char* const CONTROL_MANAGER_UNIT_SERVER_ALIAS = "unit-server-alias";
+static const char* const OPT_NODEUID = "node-uid";
+static const char* OPT_GROUP_NAME                          ="group-name";
 
 #if ENABLE_ZMQ_MONITOR
 static const char* const OPT_ENABLE_ZMQ_MONITOR = "zmq-monitor";
@@ -179,6 +179,7 @@ static const unsigned int GlobalDirectIOTimeoutinMSec = 5000;
 }  // namespace common
 namespace common {
 namespace constants {
+static const char* CHAOS_ADMIN_ADMIN_TOPIC = "CHAOS_ADMIN";
 // hearth beat timers
 static const unsigned int HBTimersTimeoutinMSec                 = 5000;
 static const unsigned int AgentTimersTimeoutinMSec              = 5000;
@@ -245,6 +246,8 @@ static const char* const NODE_SUB_TYPE = "ndk_sub_type";
          that is given by the network broker where the node si attacched.
          */
 static const char* const NODE_RPC_ADDR = "ndk_rpc_addr";
+static const char* const NODE_IP_ADDR = "ndk_ip_addr";
+
 
 //! identify the node rest port if any
 /*!
@@ -1717,6 +1720,8 @@ static const char* const DEFAULT_INC = "ds_value_inc";
 //! Namespace for the domain for the unique identification key
 namespace DataPackPrefixID {
 static const char* const COMMAND_DATASET_POSTFIX = "_cmd";
+static const char* const COMMAND_IO_POSTFIX = "_io";
+
 static const char* const LOG_DATASET_POSTFIX     = "_log";
 
 static const char* const OUTPUT_DATASET_POSTFIX    = "_o";
diff --git a/chaos/common/configuration/GlobalConfiguration.cpp b/chaos/common/configuration/GlobalConfiguration.cpp
index 0b4ac3fc65c963b6f21ef38e1eb84ec53973119e..46fb7c681056ba2a60a03c42ed128e823e50729f 100644
--- a/chaos/common/configuration/GlobalConfiguration.cpp
+++ b/chaos/common/configuration/GlobalConfiguration.cpp
@@ -88,7 +88,7 @@ void GlobalConfiguration::preParseStartupParameters()  {
         addOption(InitOption::OPT_DIRECT_IO_SERVER_IMPL_KV_PARAM, po::value< std::vector<std::string> >(),"DirectIO implementation key value parameters[k:v]");
         addOption(InitOption::OPT_DIRECT_IO_CLIENT_IMPL_KV_PARAM, po::value< std::vector<std::string> >(),"DirectIO implementation key value parameters[k:v]");
         addOption(InitOption::OPT_RPC_SYNC_ENABLE, po::value< bool >()->default_value(false), "Enable the sync wrapper to rpc protocol");
-        addOption(InitOption::OPT_RPC_IMPLEMENTATION, po::value< string >()->default_value("ZMQ"), "Specify the rpc implementation");
+        addOption(InitOption::OPT_RPC_IMPLEMENTATION, po::value< string >()->default_value("PSM"), "Specify the rpc implementation");
         addOption(InitOption::OPT_RPC_SERVER_PORT, po::value<uint32_t>()->default_value(_RPC_PORT), "RPC server port");
         addOption(InitOption::OPT_RPC_SERVER_THREAD_NUMBER, po::value<uint32_t>()->default_value(2),"RPC server thread number");
         addOption(InitOption::OPT_RPC_IMPL_KV_PARAM, po::value< std::vector<std::string> >(),"RPC implementation key value parameter[k:v]");
@@ -118,7 +118,9 @@ void GlobalConfiguration::preParseStartupParameters()  {
 #endif
         addOption(InitOption::OPT_MSG_BROKER_SERVER, po::value< std::string >()->default_value(std::string("localhost:9092")), "Message broker");
         addOption(InitOption::OPT_MSG_BROKER_DRIVER, po::value< std::string >()->default_value(std::string("kafka-rdk")), "Message broker driver");
-        addOption(InitOption::CONTROL_MANAGER_UNIT_SERVER_ALIAS, po::value< std::string >()/*->default_value(std::string("NONAME"))*/,"UID of the node");
+        addOption(InitOption::OPT_GROUP_NAME, po::value< std::string >()->default_value(std::string("")), "Group Name");
+
+        addOption(InitOption::OPT_NODEUID, po::value< std::string >()/*->default_value(std::string("NONAME"))*/,"UID of the node");
 
 
 #
@@ -235,6 +237,12 @@ void GlobalConfiguration::parseParameter(const po::basic_parsed_options<char>& o
     //check the default option
     checkDefaultOption();
 }
+#define CHECK_AND_DEFINE_CONFIG_OPTION(t,y)\
+{t x;\
+if(hasOption(y)){\
+x = getOption<t>(y);\
+configuration->append(y,x);}}
+
 void GlobalConfiguration::checkDefaultOption()  {
     configuration.reset(new CDataWrapper());
     //now we can fill the gloabl configuration
@@ -257,9 +265,6 @@ void GlobalConfiguration::checkDefaultOption()  {
     CHECK_AND_DEFINE_OPTION(string, logFilePath, InitOption::OPT_LOG_FILE);
     configuration->addStringValue(InitOption::OPT_LOG_FILE, logFilePath);
     
-    CHECK_AND_DEFINE_OPTION(string, nodeDesc, InitOption::OPT_NODE_DESC);
-    configuration->addStringValue(InitOption::OPT_NODE_DESC, nodeDesc);
-
     CHECK_AND_DEFINE_OPTION(string, logLevel, InitOption::OPT_LOG_LEVEL)
     configuration->addInt32Value(InitOption::OPT_LOG_LEVEL, filterLogLevel(logLevel));
     
@@ -283,7 +288,15 @@ void GlobalConfiguration::checkDefaultOption()  {
     
     CHECK_AND_DEFINE_OPTION(string, rpcImpl, InitOption::OPT_RPC_IMPLEMENTATION)
     configuration->addStringValue(InitOption::OPT_RPC_IMPLEMENTATION, rpcImpl);
-    
+
+    CHECK_AND_DEFINE_CONFIG_OPTION(std::string,InitOption::OPT_MSG_BROKER_SERVER);
+    CHECK_AND_DEFINE_CONFIG_OPTION(std::string,InitOption::OPT_NODE_DESC);
+    CHECK_AND_DEFINE_CONFIG_OPTION(std::string,chaos::InitOption::OPT_NODEUID);
+    CHECK_AND_DEFINE_CONFIG_OPTION(std::string,InitOption::OPT_MSG_BROKER_DRIVER);
+    #if defined(KAFKA_RDK_ENABLE) || defined(KAFKA_ASIO_ENABLE)
+    CHECK_AND_DEFINE_CONFIG_OPTION(std::vector<std::string>,InitOption::OPT_MSG_PRODUCER_KVP);
+    CHECK_AND_DEFINE_CONFIG_OPTION(std::vector<std::string>,InitOption::OPT_MSG_CONSUMER_KVP);
+    #endif
     CHECK_AND_DEFINE_OPTION(bool, OPT_RPC_SYNC_ENABLE, InitOption::OPT_RPC_SYNC_ENABLE)
     else{
         OPT_RPC_SYNC_ENABLE = false;
@@ -320,7 +333,9 @@ void GlobalConfiguration::checkDefaultOption()  {
         fillKVParameter(map_kv_param_directio_clnt_impl, directio_clnt_impl_kv_param, "");
     }
     CHECK_AND_DEFINE_OPTION(string, direct_io_server_impl, InitOption::OPT_DIRECT_IO_IMPLEMENTATION)
-    configuration->addStringValue(common::direct_io::DirectIOConfigurationKey::DIRECT_IO_IMPL_TYPE, direct_io_server_impl);
+    if(direct_io_server_impl.size()){
+        configuration->addStringValue(common::direct_io::DirectIOConfigurationKey::DIRECT_IO_IMPL_TYPE, direct_io_server_impl);
+    }
     
     CHECK_AND_DEFINE_OPTION_WITH_DEFAULT(uint32_t, direct_io_priority_port, InitOption::OPT_DIRECT_IO_PRIORITY_SERVER_PORT, _DIRECT_IO_PRIORITY_PORT);
     freeFoundPort = InetUtility::scanForLocalFreePort(direct_io_priority_port);
@@ -537,6 +552,10 @@ string GlobalConfiguration::getLocalServerAddress() {
 std::string GlobalConfiguration::getDesc(){
     return configuration->getStringValue(chaos::InitOption::OPT_NODE_DESC);
 
+}
+std::string GlobalConfiguration::getNodeUID(){
+    return configuration->getStringValue(chaos::InitOption::OPT_NODEUID);
+
 }
 
 /*
diff --git a/chaos/common/configuration/GlobalConfiguration.h b/chaos/common/configuration/GlobalConfiguration.h
index bcb22fe5469f1b825d1ab2f077a80658eebc454e..eab2b35895af419b880a4a0327c3fe832f36d4a0 100644
--- a/chaos/common/configuration/GlobalConfiguration.h
+++ b/chaos/common/configuration/GlobalConfiguration.h
@@ -72,6 +72,8 @@ t x;\
 if(hasOption(y)){\
 x = getOption<t>(y);\
 }
+
+
     
 #define CHECK_AND_DEFINE_BOOL_ZERO_TOKEN_OPTION(x,y)\
 bool x;\
@@ -299,6 +301,8 @@ x = hasOption(y);
         //!return the optional description of the node
         std::string getDesc();
         
+        //!return the nodeuid
+        std::string getNodeUID();
         /*
          return the address of metadataserver
          */
diff --git a/chaos/common/data/cache/AttributeCache.cpp b/chaos/common/data/cache/AttributeCache.cpp
index df0f9af4dfb0062f8b0bf43460be1fac3d08be24..0394ddd3367a48a8fd75e57977bca3904079dc57 100644
--- a/chaos/common/data/cache/AttributeCache.cpp
+++ b/chaos/common/data/cache/AttributeCache.cpp
@@ -49,7 +49,7 @@ void AttributeCache::addAttribute(const string& name,
                                   chaos::DataType::DataType type,
                                   const std::vector<chaos::DataType::BinarySubtype>& sub_type) {
     if(mapAttributeNameIndex.count(name))  {
-        LERR_<<__PRETTY_FUNCTION__<<" Attribute name '"<<name<<"' exists";
+        LDBG_<<__PRETTY_FUNCTION__<<" Attribute name '"<<name<<"' exists";
         return;
     }
     
@@ -88,7 +88,7 @@ void AttributeCache::addAttribute(const string& name,
 void AttributeCache::addAttribute(const std::string& name,
                                   const chaos::common::data::CDataVariant& value) {
     if(mapAttributeNameIndex.count(name)) {
-        LERR_<<__PRETTY_FUNCTION__<<" Attribute name '"<<name<<"' exists";
+        LDBG_<<__PRETTY_FUNCTION__<<" Attribute name '"<<name<<"' exists";
         return;
     }
     uint32_t size;
diff --git a/chaos/common/direct_io/impl/PSMDirectIOClient.cpp b/chaos/common/direct_io/impl/PSMDirectIOClient.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5655fc40bd4885fad9d82e506093b83768cd3dac
--- /dev/null
+++ b/chaos/common/direct_io/impl/PSMDirectIOClient.cpp
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2012, 2017 INFN
+ *
+ * Licensed under the EUPL, Version 1.2 or – as soon they
+ * will be approved by the European Commission - subsequent
+ * versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the
+ * Licence.
+ * You may obtain a copy of the Licence at:
+ *
+ * https://joinup.ec.europa.eu/software/page/eupl
+ *
+ * Unless required by applicable law or agreed to in
+ * writing, software distributed under the Licence is
+ * distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied.
+ * See the Licence for the specific language governing
+ * permissions and limitations under the Licence.
+ */
+#include <chaos/common/utility/UUIDUtil.h>
+#include <chaos/common/utility/InetUtility.h>
+#include <chaos/common/direct_io/impl/PSMDirectIOClient.h>
+#include <chaos/common/data/cache/FastHash.h>
+
+#include <boost/algorithm/string.hpp>
+#include <boost/format.hpp>
+
+#include <string.h>
+#include <assert.h>     /* assert */
+
+#define PSMDIO_LOG_HEAD "["<<getName()<<"] - "
+
+#define PSMDIOLAPP_ LAPP_ << PSMDIO_LOG_HEAD
+#define PSMDIOLDBG_ LDBG_ << PSMDIO_LOG_HEAD << __FUNCTION__ << " - "
+#define PSMDIOLERR_ LERR_ << PSMDIO_LOG_HEAD
+
+using namespace chaos::common::utility;
+
+using namespace chaos::common::direct_io;
+using namespace chaos::common::direct_io::impl;
+
+typedef boost::unique_lock<boost::shared_mutex>	PSMDirectIOClientWriteLock;
+typedef boost::shared_lock<boost::shared_mutex> PSMDirectIOClientReadLock;
+
+DEFINE_CLASS_FACTORY(PSMDirectIOClient, DirectIOClient);
+
+//------------------------------STATIC METHOD---------------------------------
+
+
+PSMDirectIOClient::PSMDirectIOClient(std::string alias):
+DirectIOClient(alias),
+priority_port(0),
+service_port(0),
+thread_run(false),
+zmq_context(NULL){};
+
+PSMDirectIOClient::~PSMDirectIOClient(){};
+
+//! Initialize instance
+void PSMDirectIOClient::init(void *init_data)  {
+    int err = 0;
+    MapPSMConfiguration default_configuration;
+    default_configuration["PSM_IO_THREADS"] = "1";
+    
+    DirectIOClient::init(init_data);
+    PSMDIOLDBG_ << "Allocating zmq context";
+    thread_run= true;
+    zmq_context = zmq_ctx_new();
+    if(zmq_context == NULL) throw chaos::CException(0, "Error creating zmq context", __FUNCTION__);
+    if((err = PSMBaseClass::configureContextWithStartupParameter(zmq_context,
+                                                                 default_configuration,
+                                                                 chaos::GlobalConfiguration::getInstance()->getDirectIOClientImplKVParam(),
+                                                                 "PSM DirectIO Client"))) {
+        throw chaos::CException(2, "Error configuring service socket", __FUNCTION__);
+    }
+    
+    
+    PSMDIOLDBG_ << "Inizilizing zmq implementation with zmq lib version = " << PSM_VERSION;
+    PSMDIOLDBG_ << "Set number of thread for the contex";
+    zmq_ctx_set(zmq_context, PSM_IO_THREADS, 2);
+    
+    PSMDIOLDBG_ << "Initialized";
+}
+
+//! Deinit the implementation
+void PSMDirectIOClient::deinit()  {
+    int err = 0;
+    //remove all active connection (never need to be exists at this step)
+    map_connections.clearElement();
+    //destroy the zmq context
+    PSMDIOLDBG_ << "Destroing zmq context";
+    thread_run = false;
+    err = zmq_ctx_destroy(zmq_context);
+    if(err) PSMDIOLERR_ << "Error closing context";
+    //monitor_thread_group.join_all();
+    
+    zmq_context = NULL;
+    PSMDIOLDBG_ << "PSM context destroyed";
+    DirectIOClient::deinit();
+}
+
+DirectIOClientConnection *PSMDirectIOClient::_getNewConnectionImpl(std::string server_description,
+                                                                   uint16_t endpoint) {
+    //allocate client
+    PSMDirectIOClientConnection *connection = new PSMDirectIOClientConnection(zmq_context,
+                                                                              server_description,
+                                                                              endpoint);
+    if(connection == NULL) return NULL;
+    try{
+        InizializableService::initImplementation(connection, NULL, "PSMDirectIOClientConnection", __PRETTY_FUNCTION__);
+        //register client with the hash of the xzmq decoded endpoint address (tcp://ip:port)
+        DEBUG_CODE(PSMDIOLDBG_ << "Register client for " << server_description << " with zmq decoded hash " << connection->getUniqueUUID();)
+        map_connections.registerElement(connection->getUniqueUUID(), connection);
+    } catch (...) {
+        PSMDIOLERR_ << CHAOS_FORMAT("We got error initilizing connection to %1%:%2% so we goning to deinitilize it an return NULL channel", %server_description%endpoint);
+        //in case of error
+        CHAOS_NOT_THROW(InizializableService::deinitImplementation(connection, "PSMDirectIOClientConnection", __PRETTY_FUNCTION__););
+        connection = NULL;
+    }
+    return connection;
+}
+
+void PSMDirectIOClient::_releaseConnectionImpl(DirectIOClientConnection *connection_to_release) {
+    PSMDirectIOClientConnection *conn=reinterpret_cast<PSMDirectIOClientConnection*>(connection_to_release);
+    if(!conn) return;
+    CHAOS_NOT_THROW(InizializableService::deinitImplementation(conn, "PSMDirectIOClientConnection", __PRETTY_FUNCTION__););
+    //CHAOS_ASSERT(conn->monitor_info)
+    //stop the monitor
+    DEBUG_CODE(PSMDIOLDBG_ << "Release the connection for: " << connection_to_release->getServerDescription() <<" ptr:"<<std::hex<<(uint64_t)connection_to_release;)
+    map_connections.deregisterElementKey(conn->getUniqueUUID());
+    delete(connection_to_release);
+}
+
+void PSMDirectIOClient::freeObject(const DCKeyObjectContainer::TKOCElement& element) {
+    if(!element.element) return;
+    DirectIOClientConnection *connection = element.element;
+    DEBUG_CODE(PSMDIOLDBG_ << "Autorelease connection for " << connection->getServerDescription();)
+    releaseConnection(connection);
+}
diff --git a/chaos/common/direct_io/impl/PSMDirectIOClient.h b/chaos/common/direct_io/impl/PSMDirectIOClient.h
new file mode 100644
index 0000000000000000000000000000000000000000..963614abc12256b5aeadc444c27e145a79796ba3
--- /dev/null
+++ b/chaos/common/direct_io/impl/PSMDirectIOClient.h
@@ -0,0 +1,90 @@
+
+/*
+ *	PSMDirectIOClient.h
+ *	!CHAOS
+ *	Created by Bisegni Claudio.
+ *
+ *    	Copyright 2012 INFN, National Institute of Nuclear Physics
+ *
+ *    	Licensed under the Apache License, Version 2.0 (the "License");
+ *    	you may not use this file except in compliance with the License.
+ *    	You may obtain a copy of the License at
+ *
+ *    	http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    	Unless required by applicable law or agreed to in writing, software
+ *    	distributed under the License is distributed on an "AS IS" BASIS,
+ *    	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    	See the License for the specific language governing permissions and
+ *    	limitations under the License.
+ */
+#ifndef __CHAOSFramework__PSMDirectIOClient__
+#define __CHAOSFramework__PSMDirectIOClient__
+
+#include <map>
+
+#include <chaos/common/direct_io/DirectIOClient.h>
+#include <chaos/common/utility/ObjectFactoryRegister.h>
+#include <chaos/common/direct_io/impl/PSMDirectIOClientConnection.h>
+
+#include <boost/thread.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include <zmq.h>
+
+namespace chaos {
+	namespace common {
+		namespace direct_io {
+			namespace channel {
+				class DirectIOVirtualClientChannel;
+			}
+            namespace impl {
+				
+				// PSM Direct IO Implementation
+				/*!
+				 */
+                DECLARE_CLASS_FACTORY(PSMDirectIOClient, DirectIOClient),
+                private PSMBaseClass {
+                    REGISTER_AND_DEFINE_DERIVED_CLASS_FACTORY_HELPER(PSMDirectIOClient)
+
+					friend class DirectIOVirtualClientChannel;
+					
+                    int32_t priority_port;
+					
+					int32_t service_port;
+
+					void *zmq_context;
+					
+					bool thread_run;
+					boost::thread_group monitor_thread_group;
+                    
+					std::map<uint32_t, ConnectionMonitorInfo*> map_connection_socket_monitor;
+					
+					PSMDirectIOClient(std::string alias);
+                    
+                    ~PSMDirectIOClient();
+					
+				protected:
+					//overriding ofr free object fuunction for the tempalted key object container superclass
+                    void freeObject(const DCKeyObjectContainer::TKOCElement& element);
+                    
+                    //! get new connection
+                    DirectIOClientConnection *_getNewConnectionImpl(std::string server_description, uint16_t endpoint);
+                    
+                    //! release an instantiated connection
+                    void _releaseConnectionImpl(DirectIOClientConnection *connection_to_release);
+                public:
+                    
+                    //! Initialize instance
+                    void init(void *init_data);
+
+                    
+                    //! Deinit the implementation
+                    void deinit();
+                };
+            }
+        }
+    }
+}
+
+#endif /* defined(__CHAOSFramework__DirectIOPSMClient__) */
diff --git a/chaos/common/direct_io/impl/PSMDirectIOServer.cpp b/chaos/common/direct_io/impl/PSMDirectIOServer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8fa505cd073ec6ec7bf67adc34ba6ce27d1ab6be
--- /dev/null
+++ b/chaos/common/direct_io/impl/PSMDirectIOServer.cpp
@@ -0,0 +1,259 @@
+/*
+ * Copyright 2012, 2017 INFN
+ *
+ * Licensed under the EUPL, Version 1.2 or – as soon they
+ * will be approved by the European Commission - subsequent
+ * versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the
+ * Licence.
+ * You may obtain a copy of the Licence at:
+ *
+ * https://joinup.ec.europa.eu/software/page/eupl
+ *
+ * Unless required by applicable law or agreed to in
+ * writing, software distributed under the Licence is
+ * distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied.
+ * See the Licence for the specific language governing
+ * permissions and limitations under the Licence.
+ */
+
+#include <chaos/common/configuration/GlobalConfiguration.h>
+#include <chaos/common/utility/UUIDUtil.h>
+#include <chaos/common/data/CDataWrapper.h>
+#include <chaos/common/direct_io/DirectIODataPack.h>
+#include <chaos/common/direct_io/impl/PSMDirectIOServer.h>
+#include <boost/format.hpp>
+
+
+#define PSMDIO_SRV_LOG_HEAD "["<<getName()<<"] - "
+
+#define PSMS_LAPP LAPP_ << PSMDIO_SRV_LOG_HEAD
+#define PSMDIO_SRV_LDBG_ LDBG_ << PSMDIO_SRV_LOG_HEAD
+#define PSMDIO_SRV_LERR_ LERR_ << PSMDIO_SRV_LOG_HEAD
+
+
+#define DIRECTIO_FREE_ANSWER_DATA(x)\
+if(x && x->answer_data) free(x->answer_data);\
+if(x) free(x);\
+x = NULL;
+
+
+namespace chaos_data = chaos::common::data;
+
+using namespace chaos::common::direct_io::impl;
+using namespace chaos::common::direct_io;
+
+DEFINE_CLASS_FACTORY(PSMDirectIOServer, DirectIOServer);
+
+PSMDirectIOServer::PSMDirectIOServer(std::string alias):
+DirectIOServer(alias),
+run_server(false),
+direct_io_thread_number(2){};
+
+PSMDirectIOServer::~PSMDirectIOServer(){};
+
+//! Initialize instance
+void PSMDirectIOServer::init(void *init_data)  {
+    CDataWrapper *cfg = reinterpret_cast<CDataWrapper*>(init_data);
+    PSMS_LAPP << "initialization";
+   try{
+    if(!cfg->hasKey(InitOption::OPT_MSG_BROKER_SERVER)){
+        throw chaos::CException(-1, "a not empty broker must be given", __PRETTY_FUNCTION__);
+    }
+    if(!cfg->hasKey(chaos::InitOption::OPT_NODEUID)){
+      throw chaos::CException(-1, "a not empty and unique id must be given", __PRETTY_FUNCTION__);
+    }
+    nodeuid      = cfg->getStringValue(chaos::InitOption::OPT_NODEUID);
+    std::string msgbrokerdrv = "kafka-rdk";
+    if(cfg->hasKey(InitOption::OPT_MSG_BROKER_DRIVER)){
+        msgbrokerdrv     = cfg->getStringValue(chaos::InitOption::OPT_MSG_BROKER_DRIVER);
+
+    }
+    
+    std::string msgbroker = cfg->getStringValue(InitOption::OPT_MSG_BROKER_SERVER);
+    std::string gname;
+    if(cfg->hasKey(InitOption::OPT_GROUP_NAME)){
+        gname=cfg->getStringValue(InitOption::OPT_GROUP_NAME);
+        PSMS_LAPP << "belong to group:\""<<gname<<"\"";
+
+    } else {
+        gname=nodeuid;
+    }
+
+    cons = chaos::common::message::MessagePSDriver::getNewConsumerDriver(msgbrokerdrv, gname);
+    prod = chaos::common::message::MessagePSDriver::getProducerDriver(msgbrokerdrv);
+
+    if (cons.get() == 0) {
+      throw chaos::CException(-3, "cannot initialize Publish Subscribe Consumer of topic:" + nodeuid  __PRETTY_FUNCTION__);
+    }
+    cons->addServer(msgbroker);
+    prod->addServer(msgbroker);
+    // subscribe to the queue of commands
+    cons->addHandler(chaos::common::message::MessagePublishSubscribeBase::ONARRIVE, boost::bind(&PSMDirectIOServer::messageHandler, this, _1));
+    cons->addHandler(chaos::common::message::MessagePublishSubscribeBase::ONERROR, boost::bind(&PSMDirectIOServer::messageError, this, _1));
+    if (cons->applyConfiguration() != 0) {
+        throw chaos::CException(-1, "cannot initialize Publish Subscribe:" + cons->getLastError(), __PRETTY_FUNCTION__);
+    }
+   
+    } catch (std::exception& e) {
+        throw CException(-2, e.what(), __PRETTY_FUNCTION__);
+    } catch (...) {
+        throw CException(-3, "generic error",  __PRETTY_FUNCTION__);
+    }
+    DirectIOServer::init(init_data);
+    
+    
+}
+
+//! Start the implementation
+void PSMDirectIOServer::start()  {
+    int err = 0;
+    
+    direct_io_thread_number = 1;
+    DirectIOServer::start();
+    
+    PSMS_LAPP << "Subscribing to " << nodeuid + chaos::DataPackPrefixID::COMMAND_IO_POSTFIX;
+    cons->subscribe(nodeuid + chaos::DataPackPrefixID::COMMAND_IO_POSTFIX);
+    cons->start();
+    prod->start();
+}
+
+//! Stop the implementation
+void PSMDirectIOServer::stop()  {
+    run_server = false;
+    DirectIOServer::stop();
+    
+    cons->stop();
+}
+
+//! Deinit the implementation
+void PSMDirectIOServer::deinit()  {
+    //serverThreadGroup.stopGroup(true);
+    
+    DirectIOServer::deinit();
+}
+
+void PSMDirectIOServer::messageHandler( chaos::common::message::ele_t& data) {
+    int64_t seq_id=-1;
+    std::string src;
+    //chaos::common::data::CDWUniquePtr data(d.cd.release());
+    if(data.cd->hasKey(RPC_SEQ_KEY)){
+        seq_id=data.cd->getInt64Value(RPC_SEQ_KEY);
+    }
+    if(data.cd->hasKey(RpcActionDefinitionKey::CS_CMDM_ANSWER_HOST_IP)){
+        src=data.cd->getStringValue(RPC_SRC_UID);
+    }
+    PSMS_LDBG << "Message Received from node:"<<src<<" seq_id:"<<seq_id << " desc:"<<data.cd->getJSONString();
+    CDWShrdPtr result_data_pack;
+
+    if(data.cd->hasKey(RPC_SYNC_KEY) &&
+        data.cd->getBoolValue(RPC_SYNC_KEY)) {
+        
+        result_data_pack = command_handler->executeCommandSync(MOVE(data.cd));
+    } else {
+        result_data_pack = command_handler->dispatchCommand(MOVE(data.cd));
+    }
+
+    if(result_data_pack.get() && src.size()){
+        PSMS_LDBG << "Something to send back:"<<seq_id << "to node:"<<src<<" desc:"<<result_data_pack->getJSONString();
+        prod->pushMsgAsync(*result_data_pack.get(),src);
+    }
+                    
+}
+void PSMDirectIOServer::messageError( chaos::common::message::ele_t& data) {
+        PSMS_LERR  << "ERROR:";
+
+}
+void PSMDirectIOServer::worker(unsigned int w_type,
+                               DirectIOHandlerPtr delegate) {
+    int err = 0;
+    
+    std::string                 identity;
+    void						*worker_socket          = NULL;
+    bool						send_synchronous_answer = false;
+    
+    DirectIODataPackSPtr        data_pack_received;
+    DirectIODataPackSPtr        data_pack_answer;
+    
+    MapPSMConfiguration         worker_empty_default_configuration;
+    MapPSMConfiguration         worker_socket_configuration;
+    worker_socket_configuration["PSM_LINGER"] = "500";
+    worker_socket_configuration["PSM_RCVHWM"] = "1000";
+    worker_socket_configuration["PSM_SNDHWM"] = "1000";
+    worker_socket_configuration["PSM_RCVTIMEO"] = "-1";
+    worker_socket_configuration["PSM_SNDTIMEO"] = "1000";
+    
+    if((worker_socket = zmq_socket(zmq_context,
+                                   PSM_DEALER)) == NULL) {
+        PSMDIO_SRV_LERR_ << "Error creating worker socket";
+        return;
+    }
+
+    if((err = PSMBaseClass::configureSocketWithStartupParameter(worker_socket,
+                                                                worker_socket_configuration,
+                                                                worker_empty_default_configuration,
+                                                                "PSM DirectIO Server worker"))){
+        return;
+    }
+    
+    if((err = PSMBaseClass::configureSocketWithStartupParameter(worker_socket,
+                                                                worker_socket_configuration,
+                                                                worker_empty_default_configuration,
+                                                                "PSM DirectIO Server worker"))){
+        return;
+    }
+    
+    if(w_type == WorkerTypePriority) {
+        if((err = PSMBaseClass::connectSocket(worker_socket,
+                                              INPROC_PRIORITY,
+                                              "PSM Server Worker"))) {
+            PSMDIO_SRV_LERR_ << CHAOS_FORMAT("Error connecting worker socket with error %1%",%err);
+            return;
+        }
+    } else if(w_type == WorkerTypeService) {
+        if((err = PSMBaseClass::connectSocket(worker_socket,
+                                              INPROC_SERVICE,
+                                              "PSM Server Worker"))) {
+            PSMDIO_SRV_LERR_ << CHAOS_FORMAT("Error connecting worker socket with error %1%",%err);
+            return;
+        }
+    }
+    
+    PSMDIO_SRV_LDBG_ << "Entering in the thread loop for worker socket";
+    while (run_server) {
+        try {
+            if((err = reveiceDatapack(worker_socket,
+                                      identity,
+                                      data_pack_received))) {
+                data_pack_received.reset();
+                continue;
+            } else {
+                //keep track if the cleint want the answer
+                send_synchronous_answer = data_pack_received->header.dispatcher_header.fields.synchronous_answer;
+                //call handler
+                if((err = DirectIOHandlerPtrCaller(handler_impl, delegate)(MOVE(data_pack_received),
+                                                                           data_pack_answer)) == 0) {
+                    if(send_synchronous_answer &&
+                       data_pack_answer) {
+                        
+                        if((err = sendDatapack(worker_socket,
+                                               identity,
+                                               MOVE(data_pack_answer)))){
+                            PSMDIO_SRV_LERR_ << CHAOS_FORMAT("Error sending answer with code %1%", %err);
+                        }
+                    }
+                } else {
+                    PSMDIO_SRV_LERR_ << CHAOS_FORMAT("Error dispatching received message with code %1%", %err);
+                }
+            }
+        } catch (CException& ex) {
+            DECODE_CHAOS_EXCEPTION(ex)
+        }
+    }
+    PSMDIO_SRV_LDBG_ << "Leaving the thread loop for worker socket";
+    if((err = zmq_close(worker_socket))) {
+        PSMDIO_SRV_LERR_ << CHAOS_FORMAT("Error closing worker socket with error %1%",%err);
+    }
+}
diff --git a/chaos/common/direct_io/impl/PSMDirectIOServer.h b/chaos/common/direct_io/impl/PSMDirectIOServer.h
new file mode 100644
index 0000000000000000000000000000000000000000..fe175e92de06790259ddb2228a8a86860fa6e7d3
--- /dev/null
+++ b/chaos/common/direct_io/impl/PSMDirectIOServer.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2012, 2017 INFN
+ *
+ * Licensed under the EUPL, Version 1.2 or – as soon they
+ * will be approved by the European Commission - subsequent
+ * versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the
+ * Licence.
+ * You may obtain a copy of the Licence at:
+ *
+ * https://joinup.ec.europa.eu/software/page/eupl
+ *
+ * Unless required by applicable law or agreed to in
+ * writing, software distributed under the Licence is
+ * distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied.
+ * See the Licence for the specific language governing
+ * permissions and limitations under the Licence.
+ */
+#ifndef __CHAOSFramework__PSMDirectIOServer__
+#define __CHAOSFramework__PSMDirectIOServer__
+
+#include <string>
+
+#include <chaos/common/direct_io/DirectIOServer.h>
+#include <chaos/common/utility/ObjectFactoryRegister.h>
+
+#include <chaos/common/message/MessagePSDriver.h>
+
+
+namespace chaos {
+    namespace common {
+        namespace direct_io {
+            namespace impl {
+                
+                typedef enum WorkerType {
+                    WorkerTypePriority = 1,
+                    WorkerTypeService = 2
+                } WorkerType;
+                
+                DECLARE_CLASS_FACTORY(PSMDirectIOServer, DirectIOServer),
+                private PSMBaseClass {
+                    REGISTER_AND_DEFINE_DERIVED_CLASS_FACTORY_HELPER(PSMDirectIOServer)
+                    
+                    chaos::common::message::consumer_uptr_t cons;
+                    chaos::common::message::producer_uptr_t prod;
+                    void messageHandler( chaos::common::message::ele_t& data);
+                    void messageError( chaos::common::message::ele_t& data);
+
+                    
+                    PSMDirectIOServer(std::string alias);
+                    ~PSMDirectIOServer();
+                public:
+                    
+                    //! Initialize instance
+                    void init(void *init_data);
+                    
+                    //! Start the implementation
+                    void start();
+                    
+                    //! Stop the implementation
+                    void stop();
+                    
+                    //! Deinit the implementation
+                    void deinit();
+                };
+            }
+        }
+    }
+}
+
+
+#endif /* defined(__CHAOSFramework__PSMDirectIOServer__) */
diff --git a/chaos/common/io/IODirectIODriver.cpp b/chaos/common/io/IODirectIODriver.cpp
index 145951d324a6c61973ec211a4da97401eaeaf517..dabface1c454050a52853a198dab91bf9ddd0e63 100644
--- a/chaos/common/io/IODirectIODriver.cpp
+++ b/chaos/common/io/IODirectIODriver.cpp
@@ -88,7 +88,12 @@ void IODirectIODriver::init(void *_init_parameter) {
     //if(!init_parameter.client_instance) throw CException(-1, "No client configured", __PRETTY_FUNCTION__);
     
     init_parameter.endpoint_instance = NetworkBroker::getInstance()->getDirectIOServerEndpoint();
-    if(!init_parameter.endpoint_instance) throw CException(-1, "No endpoint configured", __PRETTY_FUNCTION__);
+    if(!init_parameter.endpoint_instance){
+        IODirectIODriver_LINFO_<<"No Directio Endpoint configured";
+        return;
+        //throw CException(-1, "No endpoint configured", __PRETTY_FUNCTION__);
+
+    } 
     
     //initialize client
     //InizializableService::initImplementation(init_parameter.client_instance, _init_parameter, init_parameter.client_instance->getName(), __PRETTY_FUNCTION__);
diff --git a/chaos/common/io/IODirectIOPSMsgDriver.cpp b/chaos/common/io/IODirectIOPSMsgDriver.cpp
index 16e57ccb01d10483a549b1e8302f04c59eeb93a0..cc77b47ca0c7ad1545f9db21298ed966c003a7e7 100644
--- a/chaos/common/io/IODirectIOPSMsgDriver.cpp
+++ b/chaos/common/io/IODirectIOPSMsgDriver.cpp
@@ -49,10 +49,8 @@ IODirectIOPSMsgDriver::IODirectIOPSMsgDriver(const std::string& alias)
   msgbrokerdrv = GlobalConfiguration::getInstance()->getOption<std::string>(InitOption::OPT_MSG_BROKER_DRIVER);
 
   prod = chaos::common::message::MessagePSDriver::getProducerDriver(msgbrokerdrv);
-  std::string gid;
-  if (GlobalConfiguration::getInstance()->hasOption(InitOption::CONTROL_MANAGER_UNIT_SERVER_ALIAS)) {
-    gid = GlobalConfiguration::getInstance()->getOption<std::string>(InitOption::CONTROL_MANAGER_UNIT_SERVER_ALIAS);
-  }
+  std::string gid=GlobalConfiguration::getInstance()->getNodeUID();
+  
   if (gid == "") {
     gid = "IODirectIODriver";
   }
@@ -84,7 +82,7 @@ void IODirectIOPSMsgDriver::init(void* _init_parameter) {
     prod->start();
   }
 }
-void IODirectIOPSMsgDriver::defaultHandler(const chaos::common::message::ele_t& data) {
+void IODirectIOPSMsgDriver::defaultHandler( chaos::common::message::ele_t& data) {
   std::map<std::string, chaos::common::message::msgHandler>::iterator i, end;
   {
     boost::mutex::scoped_lock ll(hmutex);
diff --git a/chaos/common/io/IODirectIOPSMsgDriver.h b/chaos/common/io/IODirectIOPSMsgDriver.h
index 622bb61bfcc9942bc9ee4f85d32c86ce3ce2e3ff..e8b65048ded66c3fa889dc40213951aa9a991f73 100644
--- a/chaos/common/io/IODirectIOPSMsgDriver.h
+++ b/chaos/common/io/IODirectIOPSMsgDriver.h
@@ -52,7 +52,7 @@ namespace chaos{
               std::string msgbrokerdrv;
               chaos::common::message::producer_uptr_t prod;
               chaos::common::message::consumer_uptr_t cons;
-              void defaultHandler(const chaos::common::message::ele_t& data);
+              void defaultHandler( chaos::common::message::ele_t& data);
                boost::mutex hmutex;
                std::map<std::string,chaos::common::message::msgHandler> handler_map;
             public:
diff --git a/chaos/common/message/MessagePSConsumer.cpp b/chaos/common/message/MessagePSConsumer.cpp
index 006ba33e1961ebe510db15676d9b7786b676392c..d4d4214e4ca14b5c8e713506eefd42ee119ab7d6 100644
--- a/chaos/common/message/MessagePSConsumer.cpp
+++ b/chaos/common/message/MessagePSConsumer.cpp
@@ -69,6 +69,10 @@ ele_uptr_t MessagePSConsumer::getMsg(int timeo) {
 
 int MessagePSConsumer::subscribe(const std::string& key) {
   std::string topic = key;
+  if(key.size()==0){
+      MRDERR_ << " empty subscription name";
+      return -1;
+  }
   std::replace(topic.begin(), topic.end(), '/', '.');
   std::replace(topic.begin(), topic.end(), ':', '.');
 
diff --git a/chaos/common/message/MessagePSDriver.cpp b/chaos/common/message/MessagePSDriver.cpp
index 41a3e01d91350812854ab52e331e366dc025c00d..dd1dc665238dfbb888b85bb4dfe31260dfdcf2d3 100644
--- a/chaos/common/message/MessagePSDriver.cpp
+++ b/chaos/common/message/MessagePSDriver.cpp
@@ -9,106 +9,107 @@
 
 #endif
 #ifdef KAFKA_ASIO_ENABLE
-#include "impl/kafka/asio/MessagePSKafkaAsioProducer.h"
 #include "impl/kafka/asio/MessagePSKafkaAsioConsumer.h"
+#include "impl/kafka/asio/MessagePSKafkaAsioProducer.h"
 
 #endif
 #include <chaos/common/global.h>
 
 namespace chaos {
-    namespace common {
-        namespace message {
-
-   boost::mutex MessagePSDriver::io;
-   std::map<std::string,producer_uptr_t> MessagePSDriver::producer_drv_m;
-   std::map<std::string,consumer_uptr_t> MessagePSDriver::consumer_drv_m;
-      
-    producer_uptr_t MessagePSDriver::getProducerDriver(const std::string&drvname,const std::string& k){
-    boost::mutex::scoped_lock ll(io);
-    std::map<std::string,producer_uptr_t>::iterator i=producer_drv_m.find(drvname);
-    if(i!=producer_drv_m.end()){
-        MRDDBG_<<drvname<<"] returning allocated producer:"<<std::hex<<i->second.get();
-        return i->second;
-    }
-producer_uptr_t ret;
+namespace common {
+namespace message {
+
+boost::mutex                           MessagePSDriver::io;
+std::map<std::string, producer_uptr_t> MessagePSDriver::producer_drv_m;
+std::map<std::string, consumer_uptr_t> MessagePSDriver::consumer_drv_m;
+producer_uptr_t                        MessagePSDriver::getNewProducerDriver(const std::string& drvname, const std::string& k) {
+  producer_uptr_t ret;
 #ifdef KAFKA_RDK_ENABLE
 
-                if((drvname=="KAFKA-RDK") || (drvname=="kafka-rdk")){
-                    ret.reset(new kafka::rdk::MessagePSKafkaProducer());
-                    producer_drv_m["kafka-rdk"]=ret;
-                }
+  if ((drvname == "KAFKA-RDK") || (drvname == "kafka-rdk")) {
+    ret.reset(new kafka::rdk::MessagePSKafkaProducer());
+    producer_drv_m["kafka-rdk"] = ret;
+  }
 #endif
 #ifdef KAFKA_ASIO_ENABLE
-                if((drvname=="KAFKA-ASIO")||(drvname=="kafka-asio")){
-                    ret.reset(new kafka::asio::MessagePSKafkaAsioProducer());
-                    producer_drv_m["kafka-asio"]=ret;
-
-                }
+  if ((drvname == "KAFKA-ASIO") || (drvname == "kafka-asio")) {
+    ret.reset(new kafka::asio::MessagePSKafkaAsioProducer());
+    producer_drv_m["kafka-asio"] = ret;
+  }
 #endif
-            if(ret.get()==NULL){
-                throw chaos::CException(-5,"cannot find a producer driver for:"+drvname,__PRETTY_FUNCTION__);
-
-            }
-            MRDDBG_<<drvname<<"] created producer:"<<std::hex<<ret.get();
-
-            if(GlobalConfiguration::getInstance()->hasOption(InitOption::OPT_MSG_PRODUCER_KVP)){
-                     std::vector<std::string> opt=GlobalConfiguration::getInstance()->getOption< std::vector<std::string> >(InitOption::OPT_MSG_PRODUCER_KVP);
-                    std::map<std::string,std::string> kv;
-                    GlobalConfiguration::fillKVParameter(kv ,opt,"");
-                    for(std::map<std::string,std::string>::iterator i=kv.begin();i!=kv.end();i++){
-                        ret->setOption(i->first,i->second);
-                    }
-
-            }
-            return ret;
-
-                
+  if (ret.get() == NULL) {
+    throw chaos::CException(-5, "cannot find a producer driver for:" + drvname, __PRETTY_FUNCTION__);
+  }
+  MRDDBG_ << drvname << "] created producer:" << std::hex << ret.get();
+
+  if (GlobalConfiguration::getInstance()->hasOption(InitOption::OPT_MSG_PRODUCER_KVP)) {
+    std::vector<std::string>           opt = GlobalConfiguration::getInstance()->getOption<std::vector<std::string> >(InitOption::OPT_MSG_PRODUCER_KVP);
+    std::map<std::string, std::string> kv;
+    GlobalConfiguration::fillKVParameter(kv, opt, "");
+    for (std::map<std::string, std::string>::iterator i = kv.begin(); i != kv.end(); i++) {
+      ret->setOption(i->first, i->second);
     }
-     consumer_uptr_t MessagePSDriver::getConsumerDriver(const std::string&drvname,const std::string& gid,const std::string& k){
-             std::map<std::string,consumer_uptr_t>::iterator i=consumer_drv_m.find(drvname);
-
-         consumer_uptr_t ret;
-          if(i!=consumer_drv_m.end()){
-                MRDDBG_<<drvname<<"] returning allocated consumer:"<<std::hex<<i->second.get();
-
-                return i->second;
-        }
-   #ifdef KAFKA_RDK_ENABLE
-
-                if((drvname=="KAFKA-RDK") || (drvname=="kafka-rdk")){
-                    ret.reset(new kafka::rdk::MessagePSRDKafkaConsumer(gid,k));
-                    consumer_drv_m["kafka-rdk"]=ret;
-                }
-    #endif
-    #ifdef KAFKA_ASIO_ENABLE
-                if((drvname=="KAFKA-ASIO")||(drvname=="kafka-asio")){
-                    ret.reset(new kafka::asio::MessagePSKafkaAsioConsumer(gid,k));
-                    consumer_drv_m["kafka-asio"]=ret;
-                }
-    #endif
+  }
+  return ret;
+}
+
+producer_uptr_t MessagePSDriver::getProducerDriver(const std::string& drvname, const std::string& k) {
+  producer_uptr_t ret;
+
+  boost::mutex::scoped_lock                        ll(io);
+  std::map<std::string, producer_uptr_t>::iterator i = producer_drv_m.find(drvname);
+  if (i != producer_drv_m.end()) {
+    MRDDBG_ << drvname << "] returning allocated producer:" << std::hex << i->second.get();
+    return i->second;
+  }
+  ret                     = getNewProducerDriver(drvname, k);
+  producer_drv_m[drvname] = ret;
+  return ret;
+}
+consumer_uptr_t MessagePSDriver::getNewConsumerDriver(const std::string& drvname, const std::string& gid, const std::string& k) {
+  consumer_uptr_t ret;
 
-            if(ret.get()==NULL){
-                throw chaos::CException(-5,"cannot find a consumer driver for:"+drvname,__PRETTY_FUNCTION__);
-
-            }
-            MRDDBG_<<drvname<<"] created consumer:"<<std::hex<<ret.get();
-
-            if(GlobalConfiguration::getInstance()->hasOption(InitOption::OPT_MSG_CONSUMER_KVP)){
-                     std::vector<std::string> opt=GlobalConfiguration::getInstance()->getOption< std::vector<std::string> >(InitOption::OPT_MSG_CONSUMER_KVP);
-                    std::map<std::string,std::string> kv;
-                    GlobalConfiguration::fillKVParameter(kv ,opt,"");
-                    for(std::map<std::string,std::string>::iterator i=kv.begin();i!=kv.end();i++){
-
-                        ret->setOption(i->first,i->second);
-                    }
-
-            }
-            return ret;
-
-     }
-
-
-        }
-        }
-        }
+#ifdef KAFKA_RDK_ENABLE
 
+  if ((drvname == "KAFKA-RDK") || (drvname == "kafka-rdk")) {
+    ret.reset(new kafka::rdk::MessagePSRDKafkaConsumer(gid, k));
+  }
+#endif
+#ifdef KAFKA_ASIO_ENABLE
+  if ((drvname == "KAFKA-ASIO") || (drvname == "kafka-asio")) {
+    ret.reset(new kafka::asio::MessagePSKafkaAsioConsumer(gid, k));
+  }
+#endif
+  if (ret.get() == NULL) {
+    throw chaos::CException(-5, "cannot find a consumer driver for:" + drvname, __PRETTY_FUNCTION__);
+  }
+  MRDDBG_ << drvname << "] created consumer:" << std::hex << ret.get();
+
+  if (GlobalConfiguration::getInstance()->hasOption(InitOption::OPT_MSG_CONSUMER_KVP)) {
+    std::vector<std::string>           opt = GlobalConfiguration::getInstance()->getOption<std::vector<std::string> >(InitOption::OPT_MSG_CONSUMER_KVP);
+    std::map<std::string, std::string> kv;
+    GlobalConfiguration::fillKVParameter(kv, opt, "");
+    for (std::map<std::string, std::string>::iterator i = kv.begin(); i != kv.end(); i++) {
+      ret->setOption(i->first, i->second);
+    }
+  }
+  return ret;
+}
+
+consumer_uptr_t MessagePSDriver::getConsumerDriver(const std::string& drvname, const std::string& gid, const std::string& k) {
+  std::map<std::string, consumer_uptr_t>::iterator i = consumer_drv_m.find(drvname);
+
+  consumer_uptr_t ret;
+  if (i != consumer_drv_m.end()) {
+    MRDDBG_ << drvname << "] returning allocated consumer:" << std::hex << i->second.get();
+
+    return i->second;
+  }
+  ret                     = MessagePSDriver::getNewConsumerDriver(drvname, gid, k);
+  consumer_drv_m[drvname] = ret;
+  return ret;
+}
+
+}  // namespace message
+}  // namespace common
+}  // namespace chaos
diff --git a/chaos/common/message/MessagePSDriver.h b/chaos/common/message/MessagePSDriver.h
index a046df5febdda4d0eb85d89063cb47336ad37d29..f1fbce39f648baa593b2109a9b6ee0a8c2bf165d 100644
--- a/chaos/common/message/MessagePSDriver.h
+++ b/chaos/common/message/MessagePSDriver.h
@@ -16,6 +16,8 @@ class MessagePSDriver {
     static std::map<std::string,consumer_uptr_t> consumer_drv_m;
 
     public:
+    static producer_uptr_t getNewProducerDriver(const std::string&drvname,const std::string& k="");
+    static consumer_uptr_t getNewConsumerDriver(const std::string&drvname,const std::string& gid,const std::string& k="");
     static producer_uptr_t getProducerDriver(const std::string&drvname,const std::string& k="");
     static consumer_uptr_t getConsumerDriver(const std::string&drvname,const std::string& gid,const std::string& k="");
 
diff --git a/chaos/common/message/MessagePublishSubscribeBase.h b/chaos/common/message/MessagePublishSubscribeBase.h
index e39f17e4f9c48289ef9957ed610a2aa486ed03ec..5e1eee313051c1384eb45bcf9327d1eab4ced2ce 100644
--- a/chaos/common/message/MessagePublishSubscribeBase.h
+++ b/chaos/common/message/MessagePublishSubscribeBase.h
@@ -12,8 +12,7 @@
 namespace chaos {
     namespace common {
         namespace message {
-
-            typedef struct ele {std::string key;uint32_t off;uint32_t par;chaos::common::data::CDWShrdPtr cd;} ele_t;
+            typedef struct ele {std::string key;uint32_t off;uint32_t par;chaos::common::data::CDWUniquePtr cd;} ele_t;
             typedef boost::lockfree::queue<ele_t*> msg_queue_t;
             typedef ChaosUniquePtr<ele_t> ele_uptr_t;
             //typedef std::vector<chaos::common::data::CDWShrdPtr> msg_queue_t;
@@ -24,7 +23,7 @@ namespace chaos {
 
             };
 */
-            typedef  boost::function<void(const chaos::common::message::ele_t&)> msgHandler;
+            typedef  boost::function<void(chaos::common::message::ele_t&)> msgHandler;
 
             class MessagePublishSubscribeBase {
 
diff --git a/chaos/common/message/impl/kafka/rdk/MessagePSRDKafkaConsumer.cpp b/chaos/common/message/impl/kafka/rdk/MessagePSRDKafkaConsumer.cpp
index b3e42ce64f7fad6e89f16131b01914c3fc3308bf..3137ecd573f47b3472d3ff6c35fc7fcffabc0286 100644
--- a/chaos/common/message/impl/kafka/rdk/MessagePSRDKafkaConsumer.cpp
+++ b/chaos/common/message/impl/kafka/rdk/MessagePSRDKafkaConsumer.cpp
@@ -113,7 +113,7 @@ int MessagePSRDKafkaConsumer::applyConfiguration() {
     }*/
     if (rk == NULL) {
       MRDDBG_ << "Consumer apply configuration, groupid:" << groupid;
-      if (groupid != "") {
+      if (groupid.size()) {
         if (setOption("group.id", groupid.c_str()) != 0) {
           return -2;
         }
@@ -145,7 +145,10 @@ int MessagePSRDKafkaConsumer::applyConfiguration() {
 }
 
 int MessagePSRDKafkaConsumer::subscribe(const std::string& key) {
-  MessagePSConsumer::subscribe(key);
+  int ret=MessagePSConsumer::subscribe(key);
+  if(ret!=0){
+    return ret;
+  }
   if (rk == NULL) {
     errstr = "apply configuration first!";
     MRDERR_ << errstr;
@@ -212,7 +215,7 @@ void MessagePSRDKafkaConsumer::poll() {
       d.key = rd_kafka_topic_name(rkm->rkt);
       d.off = rkm->offset;
       d.par = rkm->partition;
-      d.cd  = chaos::common::data::CDWShrdPtr(new chaos::common::data::CDataWrapper());
+      d.cd  = chaos::common::data::CDWUniquePtr(new chaos::common::data::CDataWrapper());
       d.cd->addStringValue("msg", errstr);
       d.cd->addInt32Value("err", rkm->err);
       handlers[ONERROR](d);
@@ -240,7 +243,7 @@ void MessagePSRDKafkaConsumer::poll() {
       d.off = rkm->offset;
       d.par = rkm->partition;
       try {
-        d.cd = chaos::common::data::CDWShrdPtr(new chaos::common::data::CDataWrapper((const char*)rkm->payload, rkm->len));
+        d.cd = chaos::common::data::CDWUniquePtr(new chaos::common::data::CDataWrapper((const char*)rkm->payload, rkm->len));
       } catch (chaos::CException& e) {
         stats.errs++;
         std::stringstream ss;
@@ -253,7 +256,7 @@ void MessagePSRDKafkaConsumer::poll() {
           d.off = rkm->offset;
           d.par = rkm->partition;
 
-          d.cd  = chaos::common::data::CDWShrdPtr(new chaos::common::data::CDataWrapper());
+          d.cd  = chaos::common::data::CDWUniquePtr(new chaos::common::data::CDataWrapper());
           d.cd->addStringValue("msg",ss.str());
           d.cd->addInt32Value("err",-1);
 
@@ -271,7 +274,7 @@ void MessagePSRDKafkaConsumer::poll() {
       ele->par   = rkm->partition;
 
       try {
-        ele->cd = chaos::common::data::CDWShrdPtr(new chaos::common::data::CDataWrapper((const char*)rkm->payload, rkm->len));
+        ele->cd = chaos::common::data::CDWUniquePtr(new chaos::common::data::CDataWrapper((const char*)rkm->payload, rkm->len));
       } catch (chaos::CException& e) {
         stats.errs++;
          std::stringstream ss;
@@ -283,7 +286,7 @@ void MessagePSRDKafkaConsumer::poll() {
           d.key = rd_kafka_topic_name(rkm->rkt);
           d.off = rkm->offset;
           d.par = rkm->partition;
-          d.cd  = chaos::common::data::CDWShrdPtr(new chaos::common::data::CDataWrapper());
+          d.cd  = chaos::common::data::CDWUniquePtr(new chaos::common::data::CDataWrapper());
           d.cd->addStringValue("msg",ss.str());
           d.cd->addInt32Value("err",-1);
 
diff --git a/chaos/common/network/CNodeNetworkAddress.h b/chaos/common/network/CNodeNetworkAddress.h
index d4151044f3c6959f76a1be16d1e05713dd2fdf96..6f598a87a3ccd747ce66ba440216285f32d8719a 100644
--- a/chaos/common/network/CNodeNetworkAddress.h
+++ b/chaos/common/network/CNodeNetworkAddress.h
@@ -35,12 +35,13 @@ namespace chaos {
 			struct CNetworkAddress {
 				//the ip and port for the host that run the control unit
 				std::string ip_port;
+                bool isatopic;
                 CNetworkAddress(){};
                 CNetworkAddress(const CNetworkAddress& cna):
                 ip_port(cna.ip_port){};
                 
-                CNetworkAddress(const std::string& _ip_port):
-                ip_port(_ip_port){};
+                CNetworkAddress(const std::string& _ip_port,bool _isatopic=false):
+                ip_port(_ip_port),isatopic(_isatopic){};
 			};
 			
 			//! Represent the abstraction of chaos node id of the chaos virtual node
diff --git a/chaos/common/network/NetworkBroker.cpp b/chaos/common/network/NetworkBroker.cpp
index f7218d2e8aec51a67cea893706b03f0ca8248acc..96ce6ffea2b381f6871b4c991f83e6e2c8210fe8 100644
--- a/chaos/common/network/NetworkBroker.cpp
+++ b/chaos/common/network/NetworkBroker.cpp
@@ -18,36 +18,36 @@
  * See the Licence for the specific language governing
  * permissions and limitations under the Licence.
  */
-#include <chaos/common/global.h>
-#include <boost/lexical_cast.hpp>
+#include <chaos/common/dispatcher/AbstractCommandDispatcher.h>
+#include <chaos/common/dispatcher/AbstractEventDispatcher.h>
 #include <chaos/common/event/event.h>
-#include <chaos/common/utility/InetUtility.h>
-#include <chaos/common/network/NetworkBroker.h>
-#include <chaos/common/message/MessageChannel.h>
-#include <chaos/common/message/MDSMessageChannel.h>
+#include <chaos/common/global.h>
 #include <chaos/common/message/DeviceMessageChannel.h>
-#include <chaos/common/utility/ObjectFactoryRegister.h>
+#include <chaos/common/message/MDSMessageChannel.h>
+#include <chaos/common/message/MessageChannel.h>
 #include <chaos/common/message/MessageRequestDomain.h>
-#include <chaos/common/message/PerformanceNodeChannel.h>
-#include <chaos/common/dispatcher/AbstractEventDispatcher.h>
 #include <chaos/common/message/MultiAddressMessageChannel.h>
-#include <chaos/common/dispatcher/AbstractCommandDispatcher.h>
-#include <chaos/common/rpc/RpcServer.h>
+#include <chaos/common/message/PerformanceNodeChannel.h>
+#include <chaos/common/network/NetworkBroker.h>
 #include <chaos/common/rpc/RpcClient.h>
+#include <chaos/common/rpc/RpcServer.h>
+#include <chaos/common/utility/InetUtility.h>
+#include <chaos/common/utility/ObjectFactoryRegister.h>
+#include <boost/lexical_cast.hpp>
 
 #include <chaos/common/direct_io/DirectIO.h>
 
-
 //-----------for metric collection---------
 #if (CHAOS_PROMETHEUS)
+#include <chaos/common/direct_io/DirectIODispatcherMetricCollector.h>
 #include <chaos/common/rpc/RpcClientMetricCollector.h>
 #include <chaos/common/rpc/RpcServerMetricCollector.h>
-#include <chaos/common/direct_io/DirectIODispatcherMetricCollector.h>
 #endif
 
 #define MB_LAPP LAPP_ << "[NetworkBroker]- "
+#define MB_LERR LERR_ << __PRETTY_FUNCTION__<<"- ## [NetworkBroker]- "
 
-#define INIT_STEP   0
+#define INIT_STEP 0
 #define DEINIT_STEP 1
 using namespace chaos;
 using namespace chaos::common::event;
@@ -59,24 +59,25 @@ using namespace chaos::common::message;
 /*!
  
  */
-NetworkBroker::NetworkBroker():
-//performance_session_managment(this),
-event_client(NULL),
-event_server(NULL),
-event_dispatcher(NULL),
-rpc_server(NULL),
-rpc_client(NULL),
-rpc_dispatcher(NULL),
-direct_io_dispatcher(NULL),
-direct_io_server(NULL),
-direct_io_client(NULL),
-global_request_domain(){}
+NetworkBroker::NetworkBroker()
+    :  //performance_session_managment(this),
+    event_client(NULL)
+    , event_server(NULL)
+    , event_dispatcher(NULL)
+    , rpc_server(NULL)
+    , rpc_client(NULL)
+    , rpc_dispatcher(NULL)
+    , direct_io_dispatcher(NULL)
+    , direct_io_server(NULL)
+    , direct_io_client(NULL)
+    , usepsbroker(false)
+    , global_request_domain() {}
 
 /*!
  */
 NetworkBroker::~NetworkBroker() {
-    CHAOS_NOT_THROW(stop(););
-    CHAOS_NOT_THROW(deinit(););
+  CHAOS_NOT_THROW(stop(););
+  CHAOS_NOT_THROW(deinit(););
 }
 
 /*!
@@ -84,287 +85,300 @@ NetworkBroker::~NetworkBroker() {
  * for the rpc client and server and for the dispatcher. All these are here initialized
  */
 void NetworkBroker::init(void *initData) {
-    MB_LAPP << "Init phase";
-    //get global configuration reference
-    CDataWrapper *globalConfiguration = GlobalConfiguration::getInstance()->getConfiguration();
-    
-    
-    if(!globalConfiguration) {
-        throw CException(-1, "No global configuraiton found", __PRETTY_FUNCTION__);
-    }
-    MB_LAPP << "Configuration:"<<globalConfiguration->getCompliantJSONString();
-    
+  MB_LAPP << "Init phase";
+  //get global configuration reference
+  CDataWrapper *globalConfiguration = GlobalConfiguration::getInstance()->getConfiguration();
+
+  if (!globalConfiguration) {
+    throw CException(-1, "No global configuration found", __PRETTY_FUNCTION__);
+  }
+  MB_LAPP << "Configuration:" << globalConfiguration->getCompliantJSONString();
+  
     //---------------------------- D I R E C T I/O ----------------------------
-    if(globalConfiguration->hasKey(common::direct_io::DirectIOConfigurationKey::DIRECT_IO_IMPL_TYPE)) {
-        MB_LAPP  << "Setup DirectIO sublayer";
-        string direct_io_impl = globalConfiguration->getStringValue(common::direct_io::DirectIOConfigurationKey::DIRECT_IO_IMPL_TYPE);
-        //construct the rpc server and client name
-        string direct_io_server_impl = direct_io_impl+"DirectIOServer";
-        direct_io_client_impl = direct_io_impl + "DirectIOClient";
-        MB_LAPP  << "Trying to initilize DirectIO Server: " << direct_io_server_impl;
-        direct_io_server = ObjectFactoryRegister<common::direct_io::DirectIOServer>::getInstance()->getNewInstanceByName(direct_io_server_impl);
-        if(!direct_io_server) throw CException(-2, "Error creating direct io server implementation:"+direct_io_server_impl, __PRETTY_FUNCTION__);
-        
-        //allocate the dispatcher
-        MB_LAPP  << "Allocate DirectIODispatcher";
+    if (globalConfiguration->hasKey(common::direct_io::DirectIOConfigurationKey::DIRECT_IO_IMPL_TYPE)) {
+      string direct_io_impl = globalConfiguration->getStringValue(common::direct_io::DirectIOConfigurationKey::DIRECT_IO_IMPL_TYPE);
+      MB_LAPP << "Setup DirectIO sublayer "<<direct_io_impl;
+
+      //construct the rpc server and client name
+      string direct_io_server_impl = direct_io_impl + "DirectIOServer";
+      direct_io_client_impl        = direct_io_impl + "DirectIOClient";
+      MB_LAPP << "Trying to initialize DirectIO Server: " << direct_io_server_impl;
+      direct_io_server = ObjectFactoryRegister<common::direct_io::DirectIOServer>::getInstance()->getNewInstanceByName(direct_io_server_impl);
+      if (!direct_io_server) throw CException(-2, "Error creating direct io server implementation:" + direct_io_server_impl, __PRETTY_FUNCTION__);
+
+      //allocate the dispatcher
+      MB_LAPP << "Allocate DirectIODispatcher";
 #if CHAOS_PROMETHEUS
-        // install metric awahre dispatcher subclass
-        direct_io_dispatcher = new chaos::common::direct_io::DirectIODispatcherMetricCollector();
+      // install metric awahre dispatcher subclass
+      direct_io_dispatcher = new chaos::common::direct_io::DirectIODispatcherMetricCollector();
 #else
-        direct_io_dispatcher = new common::direct_io::DirectIODispatcher();
+      direct_io_dispatcher = new common::direct_io::DirectIODispatcher();
 #endif
-        direct_io_server->setHandler(direct_io_dispatcher);
-        //initialize direct io server
-        StartableService::initImplementation(direct_io_server, static_cast<void*>(globalConfiguration), direct_io_server->getName(), __PRETTY_FUNCTION__);
-        
-        //init the my_ip variable for all client
-        //        common::direct_io::DirectIOClientConnection::my_str_ip = GlobalConfiguration::getInstance()->getLocalServerAddress();
-        //        common::direct_io::DirectIOClientConnection::my_i64_ip = STRIP_TO_UI64(common::direct_io::DirectIOClientConnection::my_str_ip).to_ulong();
-        
-        direct_io_client = ObjectFactoryRegister<common::direct_io::DirectIOClient>::getInstance()->getNewInstanceByName(direct_io_client_impl);
-        if(!direct_io_client) throw CException(-3, "Error creating direct io client implementation:"+direct_io_client_impl, __PRETTY_FUNCTION__);
-        
-        //initialize direct io client
-        InizializableService::initImplementation(direct_io_client, static_cast<void*>(globalConfiguration), direct_io_client->getName(), __PRETTY_FUNCTION__);
-        
+      direct_io_server->setHandler(direct_io_dispatcher);
+      //initialize direct io server
+      StartableService::initImplementation(direct_io_server, static_cast<void *>(globalConfiguration), direct_io_server->getName(), __PRETTY_FUNCTION__);
+
+      //init the my_ip variable for all client
+      //        common::direct_io::DirectIOClientConnection::my_str_ip = GlobalConfiguration::getInstance()->getLocalServerAddress();
+      //        common::direct_io::DirectIOClientConnection::my_i64_ip = STRIP_TO_UI64(common::direct_io::DirectIOClientConnection::my_str_ip).to_ulong();
+
+      direct_io_client = ObjectFactoryRegister<common::direct_io::DirectIOClient>::getInstance()->getNewInstanceByName(direct_io_client_impl);
+      if (!direct_io_client) throw CException(-3, "Error creating direct io client implementation:" + direct_io_client_impl, __PRETTY_FUNCTION__);
+
+      //initialize direct io client
+      InizializableService::initImplementation(direct_io_client, static_cast<void *>(globalConfiguration), direct_io_client->getName(), __PRETTY_FUNCTION__);
     }
-    
+
     //---------------------------- D I R E C T I/O ----------------------------
-    
+
     //---------------------------- E V E N T ----------------------------
-    if(!GlobalConfiguration::getInstance()->getOption<bool>(InitOption::OPT_EVENT_DISABLE)) {
-        MB_LAPP  << "Setup Event sublayer";
-        event_dispatcher = ObjectFactoryRegister<AbstractEventDispatcher>::getInstance()->getNewInstanceByName("DefaultEventDispatcher");
-        if(!event_dispatcher)
-            throw CException(-4, "Event dispatcher implementation not found", __PRETTY_FUNCTION__);
-        
-        if(!StartableService::initImplementation(event_dispatcher, static_cast<void*>(globalConfiguration), "DefaultEventDispatcher", __PRETTY_FUNCTION__))
-            throw CException(-5, "Event dispatcher has not been initialized due an error", __PRETTY_FUNCTION__);
-        
-        
-        string event_adapter_type = globalConfiguration->getStringValue(event::EventConfiguration::OPTION_KEY_EVENT_ADAPTER_IMPLEMENTATION);
-        //construct the rpc server and client name
-        string event_server_name = event_adapter_type+"EventServer";
-        string event_client_name = event_adapter_type+"EventClient";
-        
-        MB_LAPP  << "Trying to initilize Event Server: " << event_server_name;
-        event_server = ObjectFactoryRegister<EventServer>::getInstance()->getNewInstanceByName(event_server_name);
-        if(StartableService::initImplementation(event_server, static_cast<void*>(globalConfiguration), event_server->getName(), __PRETTY_FUNCTION__)){
-            //register the root handler on event server
-            event_server->setEventHanlder(event_dispatcher);
-        }
-        
-        MB_LAPP  << "Trying to initilize Event Client: " << event_client_name;
-        event_client = ObjectFactoryRegister<EventClient>::getInstance()->getNewInstanceByName(event_client_name);
-        StartableService::initImplementation(event_client, static_cast<void*>(globalConfiguration), event_client->getName(), __PRETTY_FUNCTION__);
+    if (!GlobalConfiguration::getInstance()->getOption<bool>(InitOption::OPT_EVENT_DISABLE)) {
+      MB_LAPP << "Setup Event sublayer";
+      event_dispatcher = ObjectFactoryRegister<AbstractEventDispatcher>::getInstance()->getNewInstanceByName("DefaultEventDispatcher");
+      if (!event_dispatcher)
+        throw CException(-4, "Event dispatcher implementation not found", __PRETTY_FUNCTION__);
+
+      if (!StartableService::initImplementation(event_dispatcher, static_cast<void *>(globalConfiguration), "DefaultEventDispatcher", __PRETTY_FUNCTION__))
+        throw CException(-5, "Event dispatcher has not been initialized due an error", __PRETTY_FUNCTION__);
+
+      string event_adapter_type = globalConfiguration->getStringValue(event::EventConfiguration::OPTION_KEY_EVENT_ADAPTER_IMPLEMENTATION);
+      //construct the rpc server and client name
+      string event_server_name = event_adapter_type + "EventServer";
+      string event_client_name = event_adapter_type + "EventClient";
+
+      MB_LAPP << "Trying to initilize Event Server: " << event_server_name;
+      event_server = ObjectFactoryRegister<EventServer>::getInstance()->getNewInstanceByName(event_server_name);
+      if (StartableService::initImplementation(event_server, static_cast<void *>(globalConfiguration), event_server->getName(), __PRETTY_FUNCTION__)) {
+        //register the root handler on event server
+        event_server->setEventHanlder(event_dispatcher);
+      }
+
+      MB_LAPP << "Trying to initilize Event Client: " << event_client_name;
+      event_client = ObjectFactoryRegister<EventClient>::getInstance()->getNewInstanceByName(event_client_name);
+      StartableService::initImplementation(event_client, static_cast<void *>(globalConfiguration), event_client->getName(), __PRETTY_FUNCTION__);
     }
     //---------------------------- E V E N T ----------------------------
-    
+
     //---------------------------- R P C ----------------------------
-    if(globalConfiguration->hasKey(InitOption::OPT_RPC_IMPLEMENTATION)){
-        //get the dispatcher
-        MB_LAPP  << "Setup RPC sublayer";
-        uint32_t dispatcher_type = globalConfiguration->getUInt32Value(InitOption::OPT_RPC_DOMAIN_SCHEDULER_TYPE);
-        switch(dispatcher_type) {
-            case 1:
-                MB_LAPP  << "Use SharedCommandDispatcher for RPC";
-                rpc_dispatcher = ObjectFactoryRegister<AbstractCommandDispatcher>::getInstance()->getNewInstanceByName("SharedCommandDispatcher");
-                break;
-                
-            default:
-                MB_LAPP  << "Use DefaultCommandDispatcher for RPC";
-                rpc_dispatcher = ObjectFactoryRegister<AbstractCommandDispatcher>::getInstance()->getNewInstanceByName("DefaultCommandDispatcher");
-                break;
-        }
-        
-        if(!rpc_dispatcher)
-            throw CException(-6, "Command dispatcher implementation not found", __PRETTY_FUNCTION__);
-        
-        if(!StartableService::initImplementation(rpc_dispatcher, static_cast<void*>(globalConfiguration), "DefaultCommandDispatcher", __PRETTY_FUNCTION__))
-            throw CException(-7, "Command dispatcher has not been initialized due an error", __PRETTY_FUNCTION__);
-        
-        
-        // get the rpc type to instantiate
-        string rpc_impl = globalConfiguration->getStringValue(InitOption::OPT_RPC_IMPLEMENTATION);
-        //construct the rpc server and client name
-        string rpc_server_name = rpc_impl+"Server";
-        string rpc_client_name = rpc_impl+"Client";
-        
-        MB_LAPP  << "Trying to initilize RPC Server: " << rpc_server_name;
-        rpc_server = ObjectFactoryRegister<RpcServer>::getInstance()->getNewInstanceByName(rpc_server_name);
-        if(!rpc_server) throw CException(-8, "Error allocating rpc server implementation", __PRETTY_FUNCTION__);
+    if (globalConfiguration->hasKey(InitOption::OPT_RPC_IMPLEMENTATION)) {
+      //get the dispatcher
+      MB_LAPP << "Setup RPC sublayer";
+      uint32_t dispatcher_type = globalConfiguration->getUInt32Value(InitOption::OPT_RPC_DOMAIN_SCHEDULER_TYPE);
+      switch (dispatcher_type) {
+        case 1:
+          MB_LAPP << "Use SharedCommandDispatcher for RPC";
+          rpc_dispatcher = ObjectFactoryRegister<AbstractCommandDispatcher>::getInstance()->getNewInstanceByName("SharedCommandDispatcher");
+          break;
+
+        default:
+          MB_LAPP << "Use DefaultCommandDispatcher for RPC";
+          rpc_dispatcher = ObjectFactoryRegister<AbstractCommandDispatcher>::getInstance()->getNewInstanceByName("DefaultCommandDispatcher");
+          break;
+      }
+
+      if (!rpc_dispatcher)
+        throw CException(-6, "Command dispatcher implementation not found", __PRETTY_FUNCTION__);
+
+      if (!StartableService::initImplementation(rpc_dispatcher, static_cast<void *>(globalConfiguration), "DefaultCommandDispatcher", __PRETTY_FUNCTION__))
+        throw CException(-7, "Command dispatcher has not been initialized due an error", __PRETTY_FUNCTION__);
+
+      // get the rpc type to instantiate
+      string rpc_impl = globalConfiguration->getStringValue(InitOption::OPT_RPC_IMPLEMENTATION);
+      //construct the rpc server and client name
+      string rpc_server_name = rpc_impl + "Server";
+      string rpc_client_name = rpc_impl + "Client";
+
+      MB_LAPP << "Trying to initilize RPC Server: " << rpc_server_name;
+      rpc_server = ObjectFactoryRegister<RpcServer>::getInstance()->getNewInstanceByName(rpc_server_name);
+      if (!rpc_server) throw CException(-8, "Error allocating rpc server implementation", __PRETTY_FUNCTION__);
 #if CHAOS_PROMETHEUS
-        rpc_server = new rpc::RpcServerMetricCollector(rpc_server->getName(), rpc_server);
+      rpc_server = new rpc::RpcServerMetricCollector(rpc_server->getName(), rpc_server);
 #endif
-        if(StartableService::initImplementation(rpc_server, static_cast<void*>(globalConfiguration), rpc_server->getName(), __PRETTY_FUNCTION__)) {
-            //set the handler on the rpc server
-            rpc_server->setCommandDispatcher(rpc_dispatcher);
-        }
-        
-        MB_LAPP  << "Trying to initilize RPC Client: " << rpc_client_name;
-        rpc_client = ObjectFactoryRegister<RpcClient>::getInstance()->getNewInstanceByName(rpc_client_name);
-        if(!rpc_client) throw CException(-9, "Error allocating rpc client implementation", __PRETTY_FUNCTION__);
+      if (StartableService::initImplementation(rpc_server, static_cast<void *>(globalConfiguration), rpc_server->getName(), __PRETTY_FUNCTION__)) {
+        //set the handler on the rpc server
+        rpc_server->setCommandDispatcher(rpc_dispatcher);
+      }
+
+      MB_LAPP << "Trying to initilize RPC Client: " << rpc_client_name;
+      rpc_client = ObjectFactoryRegister<RpcClient>::getInstance()->getNewInstanceByName(rpc_client_name);
+      if (!rpc_client) throw CException(-9, "Error allocating rpc client implementation", __PRETTY_FUNCTION__);
 #if CHAOS_PROMETHEUS
-        rpc_client = new rpc::RpcClientMetricCollector(rpc_client->getName(), rpc_client);
+      rpc_client = new rpc::RpcClientMetricCollector(rpc_client->getName(), rpc_client);
 #endif
-        //! connect dispatch to manage error durign request forwarding
-        rpc_client->setServerHandler(rpc_dispatcher);
-        if(StartableService::initImplementation(rpc_client, static_cast<void*>(globalConfiguration), rpc_client->getName(), __PRETTY_FUNCTION__)) {
-            //set the forwarder into dispatcher for answere
-            rpc_dispatcher->setRpcForwarder(rpc_client);
-        }
+      //! connect dispatch to manage error durign request forwarding
+      rpc_client->setServerHandler(rpc_dispatcher);
+      if (StartableService::initImplementation(rpc_client, static_cast<void *>(globalConfiguration), rpc_client->getName(), __PRETTY_FUNCTION__)) {
+        //set the forwarder into dispatcher for answere
+        rpc_dispatcher->setRpcForwarder(rpc_client);
+      }
     } else {
-        throw CException(-10, "No RPC Adapter type found in configuration", __PRETTY_FUNCTION__);
+      throw CException(-10, "No RPC Adapter type found in configuration", __PRETTY_FUNCTION__);
     }
-    MB_LAPP  << "Initialize performance session manager";
-//    StartableService::initImplementation(performance_session_managment, static_cast<void*>(globalConfiguration), "PerformanceManagment",  __PRETTY_FUNCTION__);
-    
+    MB_LAPP << "Initialize performance session manager";
+    //    StartableService::initImplementation(performance_session_managment, static_cast<void*>(globalConfiguration), "PerformanceManagment",  __PRETTY_FUNCTION__);
+
     //get host and port for fastly set it into the requests
     published_host_and_port.clear();
     getPublishedHostAndPort(published_host_and_port);
-    
+
     //create the shared message request domain
     global_request_domain.reset(new MessageRequestDomain());
+  
 }
 
 /*!
  * All rpc adapter and command siaptcer are deinitilized
  */
 void NetworkBroker::deinit() {
-    //remove global request domain before delete all, it use internally NetworBroker singleton
-    global_request_domain.reset();
-    
+  //remove global request domain before delete all, it use internally NetworBroker singleton
+  global_request_domain.reset();
     //---------------------------- D I R E C T I/O ----------------------------
-    CHAOS_NOT_THROW(InizializableService::deinitImplementation(direct_io_client, direct_io_client->getName(), __PRETTY_FUNCTION__);)
-    DELETE_OBJ_POINTER(direct_io_client);
-    
-    CHAOS_NOT_THROW(StartableService::deinitImplementation(direct_io_server, direct_io_server->getName(), "NetworkBroker::deinit");)
-    
-    DELETE_OBJ_POINTER(direct_io_server);
+    if(direct_io_client){
+      CHAOS_NOT_THROW(InizializableService::deinitImplementation(direct_io_client, direct_io_client->getName(), __PRETTY_FUNCTION__);)
+      DELETE_OBJ_POINTER(direct_io_client);
+    }
+    if(direct_io_server){
+      CHAOS_NOT_THROW(StartableService::deinitImplementation(direct_io_server, direct_io_server->getName(), "NetworkBroker::deinit");)
+
+      DELETE_OBJ_POINTER(direct_io_server);
+    }
     //---------------------------- D I R E C T I/O ----------------------------
-    
+
     //---------------------------- E V E N T ----------------------------
-    if(!GlobalConfiguration::getInstance()->getOption<bool>(InitOption::OPT_EVENT_DISABLE)) {
-        MB_LAPP  << "Deallocate all event channel";
-        for (map<string, event::channel::EventChannel*>::iterator channnelIter = active_event_channel.begin();
-             channnelIter != active_event_channel.end();
-             channnelIter++) {
-            
-            event::channel::EventChannel *eventChannelToDispose = channnelIter->second;
-            
-            if(eventChannelToDispose){
-                
-                //deinit channel
-                eventChannelToDispose->deinit();
-                
-                //dispose it
-                delete(eventChannelToDispose);
-            }
+    if (!GlobalConfiguration::getInstance()->getOption<bool>(InitOption::OPT_EVENT_DISABLE)) {
+      MB_LAPP << "Deallocate all event channel";
+      for (map<string, event::channel::EventChannel *>::iterator channnelIter = active_event_channel.begin();
+           channnelIter != active_event_channel.end();
+           channnelIter++) {
+        event::channel::EventChannel *eventChannelToDispose = channnelIter->second;
+
+        if (eventChannelToDispose) {
+          //deinit channel
+          eventChannelToDispose->deinit();
+
+          //dispose it
+          delete (eventChannelToDispose);
         }
-        MB_LAPP  << "Clear event channel map";
-        active_event_channel.clear();
-        
-        CHAOS_NOT_THROW(StartableService::deinitImplementation(event_client, event_client->getName(), __PRETTY_FUNCTION__);)
-        DELETE_OBJ_POINTER(event_client);
-        
-        CHAOS_NOT_THROW(StartableService::deinitImplementation(event_server, event_server->getName(), __PRETTY_FUNCTION__);)
-        DELETE_OBJ_POINTER(event_server);
-        
-        MB_LAPP  << "Deinit Event dispatcher";
-        CHAOS_NOT_THROW(StartableService::deinitImplementation(event_dispatcher, "DefaultEventDispatcher", __PRETTY_FUNCTION__);)
-        DELETE_OBJ_POINTER(event_dispatcher);
+      }
+      MB_LAPP << "Clear event channel map";
+      active_event_channel.clear();
+
+      CHAOS_NOT_THROW(StartableService::deinitImplementation(event_client, event_client->getName(), __PRETTY_FUNCTION__);)
+      DELETE_OBJ_POINTER(event_client);
+
+      CHAOS_NOT_THROW(StartableService::deinitImplementation(event_server, event_server->getName(), __PRETTY_FUNCTION__);)
+      DELETE_OBJ_POINTER(event_server);
+
+      MB_LAPP << "Deinit Event dispatcher";
+      CHAOS_NOT_THROW(StartableService::deinitImplementation(event_dispatcher, "DefaultEventDispatcher", __PRETTY_FUNCTION__);)
+      DELETE_OBJ_POINTER(event_dispatcher);
     }
     //---------------------------- E V E N T ----------------------------
-    
+
     //---------------------------- R P C ----------------------------
-    MB_LAPP  << "Deallocate all rpc channel";
-    for (map<string, MessageChannel*>::iterator it = active_rpc_channel.begin();
+    MB_LAPP << "Deallocate all rpc channel";
+    for (map<string, MessageChannel *>::iterator it = active_rpc_channel.begin();
          it != active_rpc_channel.end();
          it++) {
-        
-        MessageChannel *messageChannelToDispose = it->second;
-        
-        //deinit channel
-        messageChannelToDispose->deinit();
-        
-        //dispose it
-        delete(messageChannelToDispose);
+      MessageChannel *messageChannelToDispose = it->second;
+
+      //deinit channel
+      messageChannelToDispose->deinit();
+
+      //dispose it
+      delete (messageChannelToDispose);
     }
-    MB_LAPP  << "Clear rpc channel map";
+    MB_LAPP << "Clear rpc channel map";
     active_rpc_channel.clear();
-    
+
     CHAOS_NOT_THROW(StartableService::deinitImplementation(rpc_client, rpc_client->getName(), __PRETTY_FUNCTION__);)
     DELETE_OBJ_POINTER(rpc_client);
-    
+
     CHAOS_NOT_THROW(StartableService::deinitImplementation(rpc_server, rpc_server->getName(), __PRETTY_FUNCTION__);)
     DELETE_OBJ_POINTER(rpc_server);
-    
-    MB_LAPP  << "Deinit Command Dispatcher";
+
+    MB_LAPP << "Deinit Command Dispatcher";
     CHAOS_NOT_THROW(StartableService::deinitImplementation(rpc_dispatcher, "DefaultCommandDispatcher", __PRETTY_FUNCTION__);)
     DELETE_OBJ_POINTER(rpc_dispatcher);
     //---------------------------- R P C ----------------------------
-}
+  }
+
 
 /*!
  * all part are started
  */
-void NetworkBroker::start(){
-    StartableService::startImplementation(direct_io_server, direct_io_server->getName(), __PRETTY_FUNCTION__);
-    if(!GlobalConfiguration::getInstance()->getOption<bool>(InitOption::OPT_EVENT_DISABLE)) {
-        StartableService::startImplementation(event_dispatcher, "DefaultEventDispatcher", __PRETTY_FUNCTION__);
-        StartableService::startImplementation(event_server, event_server->getName(), __PRETTY_FUNCTION__);
-        StartableService::startImplementation(event_client, event_client->getName(), __PRETTY_FUNCTION__);
+void NetworkBroker::start() {
+    if(direct_io_server){
+      StartableService::startImplementation(direct_io_server, direct_io_server->getName(), __PRETTY_FUNCTION__);
+    }
+    if (!GlobalConfiguration::getInstance()->getOption<bool>(InitOption::OPT_EVENT_DISABLE)) {
+      StartableService::startImplementation(event_dispatcher, "DefaultEventDispatcher", __PRETTY_FUNCTION__);
+      StartableService::startImplementation(event_server, event_server->getName(), __PRETTY_FUNCTION__);
+      StartableService::startImplementation(event_client, event_client->getName(), __PRETTY_FUNCTION__);
     }
     StartableService::startImplementation(rpc_dispatcher, "DefaultCommandDispatcher", __PRETTY_FUNCTION__);
     StartableService::startImplementation(rpc_server, rpc_server->getName(), __PRETTY_FUNCTION__);
     StartableService::startImplementation(rpc_client, rpc_client->getName(), __PRETTY_FUNCTION__);
-//    StartableService::startImplementation(performance_session_managment, "PerformanceManagment",  __PRETTY_FUNCTION__);
+  
+  //    StartableService::startImplementation(performance_session_managment, "PerformanceManagment",  __PRETTY_FUNCTION__);
 }
 
 /*!
  * all part are started
  */
 void NetworkBroker::stop() {
-//    CHAOS_NOT_THROW(StartableService::stopImplementation(performance_session_managment, "PerformanceManagment",  __PRETTY_FUNCTION__);)
+    //    CHAOS_NOT_THROW(StartableService::stopImplementation(performance_session_managment, "PerformanceManagment",  __PRETTY_FUNCTION__);)
     CHAOS_NOT_THROW(StartableService::stopImplementation(rpc_client, rpc_client->getName(), __PRETTY_FUNCTION__);)
     CHAOS_NOT_THROW(StartableService::stopImplementation(rpc_server, rpc_server->getName(), __PRETTY_FUNCTION__);)
     CHAOS_NOT_THROW(StartableService::stopImplementation(rpc_dispatcher, "DefaultCommandDispatcher", __PRETTY_FUNCTION__);)
-    if(!GlobalConfiguration::getInstance()->getOption<bool>(InitOption::OPT_EVENT_DISABLE)) {
-        CHAOS_NOT_THROW(StartableService::stopImplementation(event_client, event_client->getName(), __PRETTY_FUNCTION__);)
-        CHAOS_NOT_THROW(StartableService::stopImplementation(event_server, event_server->getName(), __PRETTY_FUNCTION__);)
-        CHAOS_NOT_THROW(StartableService::stopImplementation(event_dispatcher, "DefaultEventDispatcher", __PRETTY_FUNCTION__);)
+    if (!GlobalConfiguration::getInstance()->getOption<bool>(InitOption::OPT_EVENT_DISABLE)) {
+      CHAOS_NOT_THROW(StartableService::stopImplementation(event_client, event_client->getName(), __PRETTY_FUNCTION__);)
+      CHAOS_NOT_THROW(StartableService::stopImplementation(event_server, event_server->getName(), __PRETTY_FUNCTION__);)
+      CHAOS_NOT_THROW(StartableService::stopImplementation(event_dispatcher, "DefaultEventDispatcher", __PRETTY_FUNCTION__);)
     }
-    CHAOS_NOT_THROW(StartableService::stopImplementation(direct_io_server, direct_io_server->getName(), __PRETTY_FUNCTION__);)
+    if(direct_io_server){
+      CHAOS_NOT_THROW(StartableService::stopImplementation(direct_io_server, direct_io_server->getName(), __PRETTY_FUNCTION__);)
+    }
+  
 }
 
 /*!
  Return the port where the rpc server has been published
  */
 int NetworkBroker::getPublishedPort() {
-    CHAOS_ASSERT(rpc_server);
-    return rpc_server->getPublishedPort();
+  CHAOS_ASSERT(rpc_server);
+  return rpc_server->getPublishedPort();
 }
 
 /*!
  Fill the parameter withe rigth value of host and port for the internale
  rpc server of message broker
  */
-void NetworkBroker::getPublishedHostAndPort(string& hostAndPort) {
-    CHAOS_ASSERT(rpc_server);
+void NetworkBroker::getPublishedHostAndPort(string &hostAndPort) {
+  CHAOS_ASSERT(rpc_server);
+  if(rpc_server->isps()){
+    hostAndPort = rpc_server->getPublishedEndpoint();
+  } else {
     hostAndPort = GlobalConfiguration::getInstance()->getLocalServerAddress();
     hostAndPort.append(":");
     hostAndPort.append(lexical_cast<string>(rpc_server->getPublishedPort()));
+  }
+
 }
 
 std::string NetworkBroker::getRPCUrl() {
-    std::string rpc_endpoint;
-    getPublishedHostAndPort(rpc_endpoint);
-    return rpc_endpoint;
+  std::string rpc_endpoint;
+  getPublishedHostAndPort(rpc_endpoint);
+  return rpc_endpoint;
 }
 
 std::string NetworkBroker::getDirectIOUrl() {
-    CHAOS_ASSERT(rpc_server);
-    return direct_io_server->getUrl();
+  if(direct_io_server==NULL){
+    if(rpc_server->isps()){
+    return "topic:"+rpc_server->getPublishedEndpoint();
+  } 
+  }
+  return direct_io_server->getUrl();
 }
 
 #pragma mark Event Registration and forwarding
@@ -374,9 +388,9 @@ std::string NetworkBroker::getDirectIOUrl() {
  \param eventAction the actio to register
  \param eventType a type for the event for which the user want to register
  */
-void NetworkBroker::registerEventAction(EventAction *eventAction, common::event::EventType eventType, const char * const identification) {
-    CHAOS_ASSERT(event_dispatcher && eventAction && !GlobalConfiguration::getInstance()->getOption<bool>(InitOption::OPT_EVENT_DISABLE));
-    event_dispatcher->registerEventAction(eventAction, eventType, identification);
+void NetworkBroker::registerEventAction(EventAction *eventAction, common::event::EventType eventType, const char *const identification) {
+  CHAOS_ASSERT(event_dispatcher && eventAction && !GlobalConfiguration::getInstance()->getOption<bool>(InitOption::OPT_EVENT_DISABLE));
+  event_dispatcher->registerEventAction(eventAction, eventType, identification);
 }
 
 //!Event Action deregistration
@@ -384,8 +398,8 @@ void NetworkBroker::registerEventAction(EventAction *eventAction, common::event:
  Deregister an event action
  */
 void NetworkBroker::deregisterEventAction(EventAction *eventAction) {
-    CHAOS_ASSERT(event_dispatcher && eventAction && !GlobalConfiguration::getInstance()->getOption<bool>(InitOption::OPT_EVENT_DISABLE));
-    event_dispatcher->deregisterEventAction(eventAction);
+  CHAOS_ASSERT(event_dispatcher && eventAction && !GlobalConfiguration::getInstance()->getOption<bool>(InitOption::OPT_EVENT_DISABLE));
+  event_dispatcher->deregisterEventAction(eventAction);
 }
 
 //!Event channel creation
@@ -394,27 +408,27 @@ void NetworkBroker::deregisterEventAction(EventAction *eventAction) {
  \param eventType is one of the value listent in EventType enum that specify the
  type of the eventfor wich we want a channel
  */
-channel::EventChannel *NetworkBroker::getNewEventChannelFromType(common::event::EventType  event_type) {
-    CHAOS_ASSERT(!GlobalConfiguration::getInstance()->getOption<bool>(InitOption::OPT_EVENT_DISABLE));
-    common::event::channel::EventChannel *new_event_channel = NULL;
-    switch (event_type) {
-        case common::event::EventTypeAlert:
-            new_event_channel = new event::channel::AlertEventChannel(this);
-            break;
-        case common::event::EventTypeInstrument:
-            new_event_channel = new event::channel::InstrumentEventChannel(this);
-            break;
-        default:
-            break;
-    }
-    //check if the channel has been created
-    if(new_event_channel){
-        new_event_channel->init();
-        boost::mutex::scoped_lock lock(muext_map_event_channel_access);
-        active_event_channel.insert(make_pair(new_event_channel->channelID, new_event_channel));
-    }
-    
-    return new_event_channel;
+channel::EventChannel *NetworkBroker::getNewEventChannelFromType(common::event::EventType event_type) {
+  CHAOS_ASSERT(!GlobalConfiguration::getInstance()->getOption<bool>(InitOption::OPT_EVENT_DISABLE));
+  common::event::channel::EventChannel *new_event_channel = NULL;
+  switch (event_type) {
+    case common::event::EventTypeAlert:
+      new_event_channel = new event::channel::AlertEventChannel(this);
+      break;
+    case common::event::EventTypeInstrument:
+      new_event_channel = new event::channel::InstrumentEventChannel(this);
+      break;
+    default:
+      break;
+  }
+  //check if the channel has been created
+  if (new_event_channel) {
+    new_event_channel->init();
+    boost::mutex::scoped_lock lock(muext_map_event_channel_access);
+    active_event_channel.insert(make_pair(new_event_channel->channelID, new_event_channel));
+  }
+
+  return new_event_channel;
 }
 //!Device channel creation
 /*!
@@ -422,13 +436,12 @@ channel::EventChannel *NetworkBroker::getNewEventChannelFromType(common::event::
  \param deviceNetworkAddress device node address
  */
 AlertEventChannel *NetworkBroker::getNewAlertEventChannel() {
-    
-    if(GlobalConfiguration::getInstance()->getOption<bool>(InitOption::OPT_EVENT_DISABLE)){
-        MB_LAPP<<"No Event Alert Instanced, EVENTS are DISABLED";
-        return NULL;
-    }
-    
-    return static_cast<event::channel::AlertEventChannel*>(NetworkBroker::getNewEventChannelFromType(event::EventTypeAlert));
+  if (GlobalConfiguration::getInstance()->getOption<bool>(InitOption::OPT_EVENT_DISABLE)) {
+    MB_LAPP << "No Event Alert Instanced, EVENTS are DISABLED";
+    return NULL;
+  }
+
+  return static_cast<event::channel::AlertEventChannel *>(NetworkBroker::getNewEventChannelFromType(event::EventTypeAlert));
 }
 
 //!Device channel creation
@@ -437,8 +450,8 @@ AlertEventChannel *NetworkBroker::getNewAlertEventChannel() {
  \param deviceNetworkAddress device node address
  */
 InstrumentEventChannel *NetworkBroker::getNewInstrumentEventChannel() {
-    CHAOS_ASSERT(!GlobalConfiguration::getInstance()->getOption<bool>(InitOption::OPT_EVENT_DISABLE));
-    return static_cast<event::channel::InstrumentEventChannel*>(NetworkBroker::getNewEventChannelFromType(event::EventTypeInstrument));
+  CHAOS_ASSERT(!GlobalConfiguration::getInstance()->getOption<bool>(InitOption::OPT_EVENT_DISABLE));
+  return static_cast<event::channel::InstrumentEventChannel *>(NetworkBroker::getNewEventChannelFromType(event::EventTypeInstrument));
 }
 
 //!Event channel deallocation
@@ -446,22 +459,22 @@ InstrumentEventChannel *NetworkBroker::getNewInstrumentEventChannel() {
  Perform the event channel deallocation
  */
 void NetworkBroker::disposeEventChannel(common::event::channel::EventChannel *event_channel_to_dispose) {
-    CHAOS_ASSERT(!GlobalConfiguration::getInstance()->getOption<bool>(InitOption::OPT_EVENT_DISABLE));
-    if(!event_channel_to_dispose) return;
-    
-    boost::mutex::scoped_lock lock(muext_map_event_channel_access);
-    
-    //check if the channel is active
-    if(active_event_channel.count(event_channel_to_dispose->channelID) == 0) return;
-    
-    //remove the channel as active
-    active_event_channel.erase(event_channel_to_dispose->channelID);
-    
-    //deallocate it
-    event_channel_to_dispose->deinit();
-    
-    //dispose it
-    delete(event_channel_to_dispose);
+  CHAOS_ASSERT(!GlobalConfiguration::getInstance()->getOption<bool>(InitOption::OPT_EVENT_DISABLE));
+  if (!event_channel_to_dispose) return;
+
+  boost::mutex::scoped_lock lock(muext_map_event_channel_access);
+
+  //check if the channel is active
+  if (active_event_channel.count(event_channel_to_dispose->channelID) == 0) return;
+
+  //remove the channel as active
+  active_event_channel.erase(event_channel_to_dispose->channelID);
+
+  //deallocate it
+  event_channel_to_dispose->deinit();
+
+  //dispose it
+  delete (event_channel_to_dispose);
 }
 
 //!message event
@@ -470,35 +483,35 @@ void NetworkBroker::disposeEventChannel(common::event::channel::EventChannel *ev
  \param event the new evento to submit
  */
 bool NetworkBroker::submitEvent(common::event::EventDescriptor *event) {
-    CHAOS_ASSERT(event_client && !GlobalConfiguration::getInstance()->getOption<bool>(InitOption::OPT_EVENT_DISABLE));
-    bool result = true;
-    try{
-        event_client->submitEvent(MOVE(EventDescriptorSPtr(event)));
-    } catch(CException& ex) {
-        result = false;
-        DECODE_CHAOS_EXCEPTION(ex);
-    }
-    return result;
+  CHAOS_ASSERT(event_client && !GlobalConfiguration::getInstance()->getOption<bool>(InitOption::OPT_EVENT_DISABLE));
+  bool result = true;
+  try {
+    event_client->submitEvent(MOVE(EventDescriptorSPtr(event)));
+  } catch (CException &ex) {
+    result = false;
+    DECODE_CHAOS_EXCEPTION(ex);
+  }
+  return result;
 }
 
 #pragma mark Action Registration
 /*
  Register actions defined by AbstractActionDescriptor instance contained in the array
  */
-void NetworkBroker::registerAction(DeclareAction* declare_action_class) {
-    CHAOS_ASSERT(declare_action_class)
-    rpc_dispatcher->registerAction(declare_action_class);
+void NetworkBroker::registerAction(DeclareAction *declare_action_class) {
+  CHAOS_ASSERT(declare_action_class)
+  rpc_dispatcher->registerAction(declare_action_class);
 }
 
 /*
  Deregister actions for a determianted domain
  */
-void NetworkBroker::deregisterAction(DeclareAction* declare_action_class) {
-    if(rpc_dispatcher&&declare_action_class){
-        rpc_dispatcher->deregisterAction(declare_action_class);
-    } else {
-        LERR_<<"declare_action_class null";
-    }
+void NetworkBroker::deregisterAction(DeclareAction *declare_action_class) {
+  if (rpc_dispatcher && declare_action_class) {
+    rpc_dispatcher->deregisterAction(declare_action_class);
+  } else {
+    LERR_ << "declare_action_class null";
+  }
 }
 
 #pragma mark Message Submission
@@ -506,14 +519,14 @@ void NetworkBroker::deregisterAction(DeclareAction* declare_action_class) {
 /*!
  Submit a message specifing the destination
  */
-bool NetworkBroker::submitMessage(const string& host,
-                                  CDWUniquePtr message) {
-    CHAOS_ASSERT(rpc_client)
-    ChaosSharedPtr<NetworkForwardInfo> nfi = ChaosMakeSharedPtr<NetworkForwardInfo>(true);
-    nfi->destinationAddr = host;
-    nfi->setMessage(MOVE(message));
-    //add answer id to datawrapper
-    return rpc_client->submitMessage(MOVE(nfi), false);
+bool NetworkBroker::submitMessage(const string &host,
+                                  CDWUniquePtr  message) {
+  CHAOS_ASSERT(rpc_client)
+  ChaosSharedPtr<NetworkForwardInfo> nfi = ChaosMakeSharedPtr<NetworkForwardInfo>(true);
+  nfi->destinationAddr                   = host;
+  nfi->setMessage(MOVE(message));
+  //add answer id to datawrapper
+  return rpc_client->submitMessage(MOVE(nfi), false);
 }
 
 //!send interparocess message
@@ -522,93 +535,89 @@ bool NetworkBroker::submitMessage(const string& host,
  to the registered rpc domain
  */
 chaos::common::data::CDWUniquePtr NetworkBroker::submitInterProcessMessage(chaos::common::data::CDWUniquePtr message,
-                                                                           bool onThisThread) {
-    CHAOS_ASSERT(rpc_dispatcher)
-    if(onThisThread) {
-        return rpc_dispatcher->executeCommandSync(MOVE(message));
-    }else{
-        return rpc_dispatcher->dispatchCommand(MOVE(message));
-    }
+                                                                           bool                              onThisThread) {
+  CHAOS_ASSERT(rpc_dispatcher)
+  if (onThisThread) {
+    return rpc_dispatcher->executeCommandSync(MOVE(message));
+  } else {
+    return rpc_dispatcher->dispatchCommand(MOVE(message));
+  }
 }
 
 /*!
  Submite a new request to send to the remote host
  */
-bool NetworkBroker::submiteRequest(const string& host,
-                                   CDWUniquePtr request,
-                                   std::string sender_node_id,
-                                   uint32_t sender_request_id) {
-    CHAOS_ASSERT(rpc_client)
-    request->addStringValue(RpcActionDefinitionKey::CS_CMDM_ANSWER_HOST_IP, published_host_and_port);
-    ChaosSharedPtr<NetworkForwardInfo> nfi = ChaosMakeSharedPtr<NetworkForwardInfo>(true);
-    if(nfi.get()){
-        nfi->destinationAddr = host;
-        nfi->sender_node_id = sender_node_id;
-        nfi->sender_request_id = sender_request_id;
-        nfi->setMessage(MOVE(request));
-        return rpc_client->submitMessage(MOVE(nfi), false); 
-    } else {
-        LERR_<<sender_request_id<<"] to '"<<host<<"' invalid NetworkForwardInfo for:'"<<published_host_and_port<<"' sender node id:"<<sender_node_id;
-
-    }
-    return false;
+bool NetworkBroker::submiteRequest(const string &host,
+                                   CDWUniquePtr  request,
+                                   std::string   sender_node_id,
+                                   uint32_t      sender_request_id) {
+  CHAOS_ASSERT(rpc_client)
+  request->addStringValue(RpcActionDefinitionKey::CS_CMDM_ANSWER_HOST_IP, published_host_and_port);
+  ChaosSharedPtr<NetworkForwardInfo> nfi = ChaosMakeSharedPtr<NetworkForwardInfo>(true);
+  if (nfi.get()) {
+    nfi->destinationAddr   = host;
+    nfi->sender_node_id    = sender_node_id;
+    nfi->sender_request_id = sender_request_id;
+    nfi->setMessage(MOVE(request));
+    return rpc_client->submitMessage(MOVE(nfi), false);
+  } else {
+    LERR_ << sender_request_id << "] to '" << host << "' invalid NetworkForwardInfo for:'" << published_host_and_port << "' sender node id:" << sender_node_id;
+  }
+  return false;
 }
 
 /*
  */
 MessageChannel *NetworkBroker::getNewMessageChannelForRemoteHost(CNetworkAddress *node_network_address,
-                                                                 EntityType type,
-                                                                 bool use_shared_request_domain) {
-    MessageChannel *channel = NULL;
-    CHAOS_ASSERT(getServiceState() == 2)
-    if(getServiceState() != 2) return NULL;
-    switch (type) {
-        case RAW:{
-            CHAOS_ASSERT(!node_network_address)
-            channel = use_shared_request_domain?
-            new MessageChannel(this,
-                               global_request_domain):
-            new MessageChannel(this);
-            break;
-        }
-        case RAW_MULTI_ADDRESS:{
-            CHAOS_ASSERT(!node_network_address)
-            channel = use_shared_request_domain?
-            new MultiAddressMessageChannel(this,
-                                           global_request_domain):
-            new MultiAddressMessageChannel(this);
-            break;
-        }
-        case DEVICE:{
-            if(!node_network_address) return NULL;
-            channel = use_shared_request_domain?
-            new DeviceMessageChannel(this,
-                                     static_cast<CDeviceNetworkAddress*>(node_network_address),
-                                     false,
-                                     global_request_domain):
-            new DeviceMessageChannel(this, static_cast<CDeviceNetworkAddress*>(node_network_address));
-            break;
-        }
-//        case PERFORMANCE:{
-//            if(!node_network_address) return NULL;
-//            channel = use_shared_request_domain?
-//            new common::message::PerformanceNodeChannel(this,
-//                                                        node_network_address,
-//                                                        performance_session_managment.getLocalDirectIOClientInstance(),
-//                                                        global_request_domain):
-//            new common::message::PerformanceNodeChannel(this,
-//                                                        node_network_address,
-//                                                        performance_session_managment.getLocalDirectIOClientInstance());
-//            break;
-//        }
+                                                                 EntityType       type,
+                                                                 bool             use_shared_request_domain) {
+  MessageChannel *channel = NULL;
+  CHAOS_ASSERT(getServiceState() == 2)
+  if (getServiceState() != 2) return NULL;
+  switch (type) {
+    case RAW: {
+      CHAOS_ASSERT(!node_network_address)
+      channel = use_shared_request_domain ? new MessageChannel(this,
+                                                               global_request_domain)
+                                          : new MessageChannel(this);
+      break;
+    }
+    case RAW_MULTI_ADDRESS: {
+      CHAOS_ASSERT(!node_network_address)
+      channel = use_shared_request_domain ? new MultiAddressMessageChannel(this,
+                                                                           global_request_domain)
+                                          : new MultiAddressMessageChannel(this);
+      break;
     }
-    //check if the channel has been created
-    if(channel){
-        channel->init();
-        boost::mutex::scoped_lock lock(mutex_map_rpc_channel_acces);
-        active_rpc_channel.insert(make_pair(channel->getChannelUUID(), channel));
+    case DEVICE: {
+      if (!node_network_address) return NULL;
+      channel = use_shared_request_domain ? new DeviceMessageChannel(this,
+                                                                     static_cast<CDeviceNetworkAddress *>(node_network_address),
+                                                                     false,
+                                                                     global_request_domain)
+                                          : new DeviceMessageChannel(this, static_cast<CDeviceNetworkAddress *>(node_network_address));
+      break;
     }
-    return channel;
+      //        case PERFORMANCE:{
+      //            if(!node_network_address) return NULL;
+      //            channel = use_shared_request_domain?
+      //            new common::message::PerformanceNodeChannel(this,
+      //                                                        node_network_address,
+      //                                                        performance_session_managment.getLocalDirectIOClientInstance(),
+      //                                                        global_request_domain):
+      //            new common::message::PerformanceNodeChannel(this,
+      //                                                        node_network_address,
+      //                                                        performance_session_managment.getLocalDirectIOClientInstance());
+      //            break;
+      //        }
+  }
+  //check if the channel has been created
+  if (channel) {
+    channel->init();
+    boost::mutex::scoped_lock lock(mutex_map_rpc_channel_acces);
+    active_rpc_channel.insert(make_pair(channel->getChannelUUID(), channel));
+  }
+  return channel;
 }
 
 //!Metadata server channel creation
@@ -616,47 +625,50 @@ MessageChannel *NetworkBroker::getNewMessageChannelForRemoteHost(CNetworkAddress
  Performe the creation of metadata server
  */
 MDSMessageChannel *NetworkBroker::getMetadataserverMessageChannel(MessageRequestDomainSHRDPtr shared_request_domain) {
-    MDSMessageChannel *channel = (shared_request_domain.get() == NULL)?
-    (new MDSMessageChannel(this, GlobalConfiguration::getInstance()->getMetadataServerAddressList(), global_request_domain)):
-    (new MDSMessageChannel(this, GlobalConfiguration::getInstance()->getMetadataServerAddressList(), shared_request_domain));
-    if(channel){
-        channel->init();
-        boost::mutex::scoped_lock lock(mutex_map_rpc_channel_acces);
-        active_rpc_channel.insert(make_pair(channel->getChannelUUID(), static_cast<MessageChannel*>(channel)));
-    }
-    return channel;
+   chaos::common::network::VectorNetworkAddress mds;
+   if(rpc_client->isps()){
+     chaos::common::network::CNetworkAddress m(common::constants::CHAOS_ADMIN_ADMIN_TOPIC,true);
+     mds.push_back(m);
+   } else {
+     mds=GlobalConfiguration::getInstance()->getMetadataServerAddressList();
+   }
+
+  MDSMessageChannel *channel = (shared_request_domain.get() == NULL) ? (new MDSMessageChannel(this,mds , global_request_domain)) : (new MDSMessageChannel(this, mds, shared_request_domain));
+  if (channel) {
+    channel->init();
+    boost::mutex::scoped_lock lock(mutex_map_rpc_channel_acces);
+    active_rpc_channel.insert(make_pair(channel->getChannelUUID(), static_cast<MessageChannel *>(channel)));
+  }
+  return channel;
 }
 /*!
  Performe the creation of metadata server
  */
-MDSMessageChannel *NetworkBroker::getMetadataserverMessageChannel(const VectorNetworkAddress& endpoints, MessageRequestDomainSHRDPtr shared_request_domain) {
-    MDSMessageChannel *channel = (shared_request_domain.get() == NULL)?
-    (new MDSMessageChannel(this, endpoints, global_request_domain)):
-    (new MDSMessageChannel(this, endpoints, shared_request_domain));
-    if(channel){
-        channel->init();
-        boost::mutex::scoped_lock lock(mutex_map_rpc_channel_acces);
-        active_rpc_channel.insert(make_pair(channel->getChannelUUID(), static_cast<MessageChannel*>(channel)));
-    }
-    return channel;
+MDSMessageChannel *NetworkBroker::getMetadataserverMessageChannel(const VectorNetworkAddress &endpoints, MessageRequestDomainSHRDPtr shared_request_domain) {
+  MDSMessageChannel *channel = (shared_request_domain.get() == NULL) ? (new MDSMessageChannel(this, endpoints, global_request_domain)) : (new MDSMessageChannel(this, endpoints, shared_request_domain));
+  if (channel) {
+    channel->init();
+    boost::mutex::scoped_lock lock(mutex_map_rpc_channel_acces);
+    active_rpc_channel.insert(make_pair(channel->getChannelUUID(), static_cast<MessageChannel *>(channel)));
+  }
+  return channel;
 }
 
-
 //!Metadata server channel creation
 /*!
  Performe the creation of metadata server
  */
 MultiAddressMessageChannel *NetworkBroker::getMultiMetadataServiceRawMessageChannel() {
-    MultiAddressMessageChannel *mc = getRawMultiAddressMessageChannel();
-    if(mc){
-        mc->addNode(GlobalConfiguration::getInstance()->getMetadataServerAddress());
-    }
-    if(mc){
-        mc->init();
-        boost::mutex::scoped_lock lock(mutex_map_rpc_channel_acces);
-        active_rpc_channel.insert(make_pair(mc->getChannelUUID(), mc));
-    }
-    return mc;
+  MultiAddressMessageChannel *mc = getRawMultiAddressMessageChannel();
+  if (mc) {
+    mc->addNode(GlobalConfiguration::getInstance()->getMetadataServerAddress());
+  }
+  if (mc) {
+    mc->init();
+    boost::mutex::scoped_lock lock(mutex_map_rpc_channel_acces);
+    active_rpc_channel.insert(make_pair(mc->getChannelUUID(), mc));
+  }
+  return mc;
 }
 
 //!Device channel creation
@@ -665,53 +677,51 @@ MultiAddressMessageChannel *NetworkBroker::getMultiMetadataServiceRawMessageChan
  \param deviceNetworkAddress device node address
  */
 DeviceMessageChannel *NetworkBroker::getDeviceMessageChannelFromAddress(CDeviceNetworkAddress *node_network_address,
-                                                                        bool self_managed,
-                                                                        bool use_shared_request_domain) {
-    DeviceMessageChannel *channel = (use_shared_request_domain?
-                                     new DeviceMessageChannel(this,
-                                                              node_network_address,
-                                                              self_managed,
-                                                              global_request_domain):
-                                     new DeviceMessageChannel(this,
-                                                              node_network_address,
-                                                              self_managed));
-    
-    
-    if(channel){
-        channel->init();
-        boost::mutex::scoped_lock lock(mutex_map_rpc_channel_acces);
-        active_rpc_channel.insert(make_pair(channel->getChannelUUID(), static_cast<MessageChannel*>(channel)));
-    }
-    return channel;
+                                                                        bool                   self_managed,
+                                                                        bool                   use_shared_request_domain) {
+  DeviceMessageChannel *channel = (use_shared_request_domain ? new DeviceMessageChannel(this,
+                                                                                        node_network_address,
+                                                                                        self_managed,
+                                                                                        global_request_domain)
+                                                             : new DeviceMessageChannel(this,
+                                                                                        node_network_address,
+                                                                                        self_managed));
+
+  if (channel) {
+    channel->init();
+    boost::mutex::scoped_lock lock(mutex_map_rpc_channel_acces);
+    active_rpc_channel.insert(make_pair(channel->getChannelUUID(), static_cast<MessageChannel *>(channel)));
+  }
+  return channel;
 }
 
 //!performance channel creation
-PerformanceNodeChannel *NetworkBroker::getPerformanceChannelFromAddress(CNetworkAddress  *node_network_address) {
-    return static_cast<chaos::common::message::PerformanceNodeChannel*>(getNewMessageChannelForRemoteHost(node_network_address, PERFORMANCE));
+PerformanceNodeChannel *NetworkBroker::getPerformanceChannelFromAddress(CNetworkAddress *node_network_address) {
+  return static_cast<chaos::common::message::PerformanceNodeChannel *>(getNewMessageChannelForRemoteHost(node_network_address, PERFORMANCE));
 }
 
 //! Return a raw message channel
 MessageChannel *NetworkBroker::getRawMessageChannel() {
-    return getNewMessageChannelForRemoteHost(NULL, RAW);
+  return getNewMessageChannelForRemoteHost(NULL, RAW);
 }
 
 //! Return a raw multinode message channel
 MultiAddressMessageChannel *NetworkBroker::getRawMultiAddressMessageChannel() {
-    return static_cast<MultiAddressMessageChannel*>(getNewMessageChannelForRemoteHost(NULL, RAW_MULTI_ADDRESS));
+  return static_cast<MultiAddressMessageChannel *>(getNewMessageChannelForRemoteHost(NULL, RAW_MULTI_ADDRESS));
 }
 
 //! Return a raw multinode message channel
 /*!
  Performe the creation of a raw multinode message channel
  */
-chaos::common::message::MultiAddressMessageChannel *NetworkBroker::getRawMultiAddressMessageChannel(const std::vector<chaos::common::network::CNetworkAddress>& node_address) {
-    MultiAddressMessageChannel *mc = new MultiAddressMessageChannel(this, node_address);
-    if(mc){
-        mc->init();
-        boost::mutex::scoped_lock lock(mutex_map_rpc_channel_acces);
-        active_rpc_channel.insert(make_pair(mc->getChannelUUID(), mc));
-    }
-    return mc;
+chaos::common::message::MultiAddressMessageChannel *NetworkBroker::getRawMultiAddressMessageChannel(const std::vector<chaos::common::network::CNetworkAddress> &node_address) {
+  MultiAddressMessageChannel *mc = new MultiAddressMessageChannel(this, node_address);
+  if (mc) {
+    mc->init();
+    boost::mutex::scoped_lock lock(mutex_map_rpc_channel_acces);
+    active_rpc_channel.insert(make_pair(mc->getChannelUUID(), mc));
+  }
+  return mc;
 }
 
 //!Channel deallocation
@@ -719,56 +729,62 @@ chaos::common::message::MultiAddressMessageChannel *NetworkBroker::getRawMultiAd
  Perform the message channel deallocation
  */
 void NetworkBroker::disposeMessageChannel(MessageChannel *message_channel_to_dispose) {
-    if(!message_channel_to_dispose) return;
-    
-    std::string uid=message_channel_to_dispose->getChannelUUID();
-    //deallocate it
-    CHAOS_NOT_THROW(message_channel_to_dispose->deinit(););
-    //check if the channel is active
+  if (!message_channel_to_dispose) return;
 
-    if(active_rpc_channel.count(uid) == 0) return;
+  std::string uid = message_channel_to_dispose->getChannelUUID();
+  //deallocate it
+  CHAOS_NOT_THROW(message_channel_to_dispose->deinit(););
+  //check if the channel is active
 
-    boost::mutex::scoped_lock lock(mutex_map_rpc_channel_acces);
-    
-    //remove the channel as active
-    active_rpc_channel.erase(uid);
-    
-    //dispose it
-    delete(message_channel_to_dispose);
+  if (active_rpc_channel.count(uid) == 0) return;
+
+  boost::mutex::scoped_lock lock(mutex_map_rpc_channel_acces);
+
+  //remove the channel as active
+  active_rpc_channel.erase(uid);
+
+  //dispose it
+  delete (message_channel_to_dispose);
 }
 //!Channel deallocation
 void NetworkBroker::disposeMessageChannel(NodeMessageChannel *messageChannelToDispose) {
-    NetworkBroker::disposeMessageChannel((MessageChannel*)messageChannelToDispose);
+  NetworkBroker::disposeMessageChannel((MessageChannel *)messageChannelToDispose);
 }
 
 //!Rpc Channel deallocation
 void NetworkBroker::disposeMessageChannel(chaos::common::message::MultiAddressMessageChannel *messageChannelToDispose) {
-    NetworkBroker::disposeMessageChannel((MessageChannel*)messageChannelToDispose);
+  NetworkBroker::disposeMessageChannel((MessageChannel *)messageChannelToDispose);
 }
 
 //!Rpc Channel deallocation
 void NetworkBroker::disposeMessageChannel(chaos::common::message::MDSMessageChannel *messageChannelToDispose) {
-    NetworkBroker::disposeMessageChannel(static_cast<MessageChannel*>(messageChannelToDispose));
+  NetworkBroker::disposeMessageChannel(static_cast<MessageChannel *>(messageChannelToDispose));
 }
 
-
 //Allocate a new endpoint in the direct io server
 chaos_direct_io::DirectIOServerEndpoint *NetworkBroker::getDirectIOServerEndpoint() {
-    CHAOS_ASSERT(direct_io_dispatcher)
-    chaos_direct_io::DirectIOServerEndpoint *result_endpoint = direct_io_dispatcher->getNewEndpoint();
-    return result_endpoint;
+  if(direct_io_dispatcher==NULL){
+    MB_LERR<<"DirectIO server disabled";
+    return NULL;
+  }
+  chaos_direct_io::DirectIOServerEndpoint *result_endpoint = direct_io_dispatcher->getNewEndpoint();
+  return result_endpoint;
 }
 //Dispose an endpoint of the direct io server
 void NetworkBroker::releaseDirectIOServerEndpoint(chaos_direct_io::DirectIOServerEndpoint *end_point) {
-    direct_io_dispatcher->releaseEndpoint(end_point);
+  direct_io_dispatcher->releaseEndpoint(end_point);
 }
 //Return a new direct io client instance
 chaos_direct_io::DirectIOClient *NetworkBroker::getSharedDirectIOClientInstance() {
-    return direct_io_client;
+  if(direct_io_client==NULL){
+    MB_LERR<<"DirectIO client disabled";
+  }
+
+  return direct_io_client;
 }
 
 //Return a new direct io client instance
 chaos_direct_io::DirectIOClient *NetworkBroker::getNewDirectIOClientInstance() {
-    MB_LAPP  << "Allocate a new DirectIOClient of type " << direct_io_client_impl;
-    return ObjectFactoryRegister<common::direct_io::DirectIOClient>::getInstance()->getNewInstanceByName(direct_io_client_impl);
+  MB_LAPP << "Allocate a new DirectIOClient of type " << direct_io_client_impl;
+  return ObjectFactoryRegister<common::direct_io::DirectIOClient>::getInstance()->getNewInstanceByName(direct_io_client_impl);
 }
diff --git a/chaos/common/network/NetworkBroker.h b/chaos/common/network/NetworkBroker.h
index fa35b9f18e0111fe3b57d7dab7600f6704c05471..03ffc6e431d844af9ddbba1212ec2f80f04bcde3 100644
--- a/chaos/common/network/NetworkBroker.h
+++ b/chaos/common/network/NetworkBroker.h
@@ -31,6 +31,7 @@
 //#include <chaos/common/network/PerformanceManagment.h>
 #include <chaos/common/utility/StartableService.h>
 #include <chaos/common/network/CNodeNetworkAddress.h>
+#include <chaos/common/message/MessagePSDriver.h>
 
 namespace chaos {
 	
@@ -155,7 +156,7 @@ namespace chaos {
                                                                                             
 			public:
 				
-				
+				bool usepsbroker;
 				//! Basic Destructor
 				virtual ~NetworkBroker();
 				
diff --git a/chaos/common/network/NetworkForwardInfo.h b/chaos/common/network/NetworkForwardInfo.h
index 90dc94a650608b91e24f57d9a2313984529ba52b..63483ed2d0e4639c0b1ff84f740bc20436403f0e 100644
--- a/chaos/common/network/NetworkForwardInfo.h
+++ b/chaos/common/network/NetworkForwardInfo.h
@@ -37,6 +37,7 @@ namespace chaos {
 			typedef struct NetworkForwardInfo {
                 bool is_request;
                 bool is_synchronous_request;
+                bool is_psm;//is publish subscribe
 				//!Define the information ip:port used to reach a remote chaos network broker
 				std::string destinationAddr;
 				//! the message data
@@ -55,6 +56,7 @@ namespace chaos {
                 destinationAddr(),
                 message(),
                 tag(0),
+                is_psm(false),
                 sender_node_id(),
                 sender_request_id(0){}
 
diff --git a/chaos/common/rpc/ChaosRpc.h b/chaos/common/rpc/ChaosRpc.h
index eb79e62bf9b41d015436f86a3b6a1d2687ec153c..ea1239ed52d6bc12e0259079d6744c192f0bf5d2 100644
--- a/chaos/common/rpc/ChaosRpc.h
+++ b/chaos/common/rpc/ChaosRpc.h
@@ -22,4 +22,5 @@
 #define ChaosFramework_ChaosRpc_h
 #define RPC_SYNC_KEY "sync"
 #define RPC_SEQ_KEY "seq_id"
+#define RPC_SRC_UID "src_uid"
 #endif
diff --git a/chaos/common/rpc/RpcClient.cpp b/chaos/common/rpc/RpcClient.cpp
index 5432223a34d6ff8af18b03d25ab9e3c3d99cda9e..5932cfd9b8e8ce287e199905505176e221af3691 100644
--- a/chaos/common/rpc/RpcClient.cpp
+++ b/chaos/common/rpc/RpcClient.cpp
@@ -36,6 +36,7 @@ using namespace chaos::common::data;
  */
 RpcClient::RpcClient(const std::string& alias):
 NamedService(alias),
+is_psm(false),
 syncrhonous_call(GlobalConfiguration::getInstance()->getConfiguration()->getBoolValue(InitOption::OPT_RPC_SYNC_ENABLE)),
 server_handler(NULL){}
 
diff --git a/chaos/common/rpc/RpcClient.h b/chaos/common/rpc/RpcClient.h
index 05c633a7124e22034344bff20e002553bde3eaf2..f24f023806d8c8ceb2498bed71d347aa4a5632fe 100644
--- a/chaos/common/rpc/RpcClient.h
+++ b/chaos/common/rpc/RpcClient.h
@@ -68,7 +68,7 @@ namespace chaos {
         //! handler to the dispatcher to forward error on data forwarding
         chaos::common::rpc::RpcServerHandler *server_handler;
     protected:
-        
+        bool is_psm; // is publish subscribe
         bool syncrhonous_call;
         
         void forwadSubmissionResult(NFISharedPtr message_info,
@@ -105,6 +105,7 @@ namespace chaos {
         //! Set dinamically the synchronousRpcFeautres
         void setSynchronousRPCState(bool _syncrhonous_call);
         bool getynchronousRPCState()const;
+        bool isps()const {return is_psm;}
     };
 }
 #endif
diff --git a/chaos/common/rpc/RpcServer.cpp b/chaos/common/rpc/RpcServer.cpp
index acf8ddf119a5d99eb523c59835a848918b24cfea..cac3b93ea83457285577864b97071bcb3b6a8719 100644
--- a/chaos/common/rpc/RpcServer.cpp
+++ b/chaos/common/rpc/RpcServer.cpp
@@ -24,6 +24,7 @@ using namespace chaos;
 
 RpcServer::RpcServer(const std::string& alias):
 NamedService(alias),
+is_psm(false),
 port_number(0),
 command_handler(NULL){}
 
@@ -37,6 +38,11 @@ void RpcServer::setAlternatePortAddress(int new_port_address) {
 int RpcServer::getPublishedPort() {
     return port_number;
 }
+std::string RpcServer::getPublishedEndpoint(){
+    std::stringstream ss;
+    ss<<":"<<port_number;
+    return ss.str();
+}
 
 /*
  set the command dispatcher associated to the instance of rpc adapter
diff --git a/chaos/common/rpc/RpcServer.h b/chaos/common/rpc/RpcServer.h
index c3ee11cb17925226304b39d5a2457b9e82bee2e1..4f9ff261f608c96caf4d5f659b64089b4ffa71ac 100644
--- a/chaos/common/rpc/RpcServer.h
+++ b/chaos/common/rpc/RpcServer.h
@@ -54,6 +54,8 @@ namespace chaos {
 	public common::utility::NamedService {
 		friend class chaos::common::network::NetworkBroker;
     protected:
+        bool is_psm; // is publish subscribe
+
         //! port where server has been published
         int port_number;
         
@@ -83,6 +85,11 @@ namespace chaos {
          Return the published port
          */
         virtual int getPublishedPort();
+
+        /*!
+         Return the published endpoint
+         */
+        virtual std::string getPublishedEndpoint();
         
         /*
          set the command dispatcher associated to the instance of rpc adapter
@@ -96,6 +103,8 @@ namespace chaos {
          of internal queue message
          */
         virtual uint64_t getMessageQueueSize();
+        bool isps()const {return is_psm;}
+
     };
 }
 #endif
diff --git a/chaos/common/rpc/psm/PSMClient.cpp b/chaos/common/rpc/psm/PSMClient.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a3638ae849c2f8a7efbb68e0931ce1f3991a3b4f
--- /dev/null
+++ b/chaos/common/rpc/psm/PSMClient.cpp
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2012, 2017 INFN
+ *
+ * Licensed under the EUPL, Version 1.2 or – as soon they
+ * will be approved by the European Commission - subsequent
+ * versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the
+ * Licence.
+ * You may obtain a copy of the Licence at:
+ *
+ * https://joinup.ec.europa.eu/software/page/eupl
+ *
+ * Unless required by applicable law or agreed to in
+ * writing, software distributed under the Licence is
+ * distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied.
+ * See the Licence for the specific language governing
+ * permissions and limitations under the Licence.
+ */
+
+#include <chaos/common/global.h>
+#include <chaos/common/rpc/ChaosRpc.h>
+#include <chaos/common/async_central/AsyncCentralManager.h>
+#include <chaos/common/chaos_constants.h>
+#include <chaos/common/configuration/GlobalConfiguration.h>
+#include <chaos/common/async_central/AsyncCentralManager.h>
+#include <string>
+#include <boost/lexical_cast.hpp>
+#include <boost/algorithm/string.hpp>
+#include <chaos/common/chaos_errors.h>
+
+using namespace chaos;
+using namespace chaos::common::data;
+using namespace std;
+using namespace boost;
+using namespace boost::algorithm;
+#include "PSMClient.h"
+#define PSMC_LAPP INFO_LOG(PSMClient)
+#define PSMC_LDBG DBG_LOG(PSMClient)
+#define PSMC_LERR ERR_LOG(PSMClient)
+
+#define PSM_DO_AGAIN(x) do{x}while(err == EAGAIN);
+#define PSM_SOCKET_MAINTENANCE_TIMEOUT (5000 * 30)
+#define PSM_SOCKET_LIFETIME_TIMEOUT (5000 * 60)
+//-------------------------------------------------------
+DEFINE_CLASS_FACTORY(PSMClient, RpcClient);
+
+PSMClient::PSMClient(const string& alias):
+RpcClient(alias){    
+    seq_id=0;
+    is_psm=true;
+
+}
+
+PSMClient::~PSMClient(){
+//    #ifndef CHAOS_PROMETHEUS
+//    delete counter_zmqerror_uptr;
+//    #endif
+}
+
+/*
+ Initialization method for output buffer
+ */
+void PSMClient::init(void *init_data) {
+    CDataWrapper *cfg = reinterpret_cast<CDataWrapper*>(init_data);
+    seq_id=0;
+    PSMC_LAPP << "initialization";
+    if(!cfg->hasKey(InitOption::OPT_MSG_BROKER_SERVER)){
+        throw chaos::CException(-1, "a not empty broker must be given", __PRETTY_FUNCTION__);
+    }
+    if(!cfg->hasKey(chaos::InitOption::OPT_NODEUID)){
+      throw chaos::CException(-1, "a not empty and unique id must be given", __PRETTY_FUNCTION__);
+    }
+    nodeuid      = cfg->getStringValue(chaos::InitOption::OPT_NODEUID);
+    std::string msgbrokerdrv = "kafka-rdk";
+    if(cfg->hasKey(InitOption::OPT_MSG_BROKER_DRIVER)){
+        msgbrokerdrv     = cfg->getStringValue(chaos::InitOption::OPT_MSG_BROKER_DRIVER);
+
+    }
+    
+    std::string msgbroker = cfg->getStringValue(InitOption::OPT_MSG_BROKER_SERVER);
+
+    prod = chaos::common::message::MessagePSDriver::getProducerDriver(msgbrokerdrv);
+        PSMC_LAPP << "Initializing producer based on " << msgbroker<<" ("+msgbrokerdrv+")";
+
+    prod->addServer(msgbroker);
+
+    if (prod->applyConfiguration() != 0) {
+      throw chaos::CException(-2, "cannot initialize Publish Subscribe Producer:" + prod->getLastError(), __PRETTY_FUNCTION__);
+    }
+
+}
+
+/*
+ start the rpc adapter
+ */
+void PSMClient::start() {
+    int err = 0;
+    prod->start();
+
+    //start timere after and repeat every one minut
+  //  if((err = chaos::common::async_central::AsyncCentralManager::getInstance()->addTimer(this, PSM_SOCKET_MAINTENANCE_TIMEOUT, PSM_SOCKET_MAINTENANCE_TIMEOUT))) {LOG_AND_TROW(PSMC_LERR, err, "Error adding timer")}
+}
+
+/*
+ start the rpc adapter
+ */
+void PSMClient::stop() {
+    int err = 0;
+    prod->stop();
+    //  if((err = chaos::common::async_central::AsyncCentralManager::getInstance()->removeTimer(this))) {LOG_AND_TROW(PSMC_LERR, err, "Error removing timer")}
+}
+
+/*
+ Deinitialization method for output buffer
+ */
+void PSMClient::deinit() {
+   
+    PSMC_LAPP << "PSM Destroyed";
+}
+
+/*
+ 
+ */
+bool PSMClient::submitMessage(NFISharedPtr forwardInfo,
+                              bool onThisThread) {
+    CHAOS_ASSERT(forwardInfo);
+    ElementManagingPolicy ePolicy;
+    try{
+        forwardInfo->is_psm=true;
+        if(!forwardInfo->destinationAddr.size())
+            throw CException(0, "No destination in message description", __PRETTY_FUNCTION__);
+        if(!forwardInfo->hasMessage())
+            throw CException(0, "No message in description", __PRETTY_FUNCTION__);
+        if(forwardInfo->message->hasKey(RpcActionDefinitionKey::CS_CMDM_ANSWER_HOST_IP)){
+            forwardInfo->message->removeKey(RpcActionDefinitionKey::CS_CMDM_ANSWER_HOST_IP);
+            forwardInfo->message->addStringValue(RpcActionDefinitionKey::CS_CMDM_ANSWER_HOST_IP,nodeuid+chaos::DataPackPrefixID::COMMAND_DATASET_POSTFIX);
+        }
+        forwardInfo->message->addBoolValue(RPC_SYNC_KEY, RpcClient::syncrhonous_call);
+        forwardInfo->message->addInt64Value(RPC_SEQ_KEY, (++seq_id));
+      
+        std::string key=forwardInfo->destinationAddr;
+        PSMC_LDBG<<"Sending message to:"<<forwardInfo->destinationAddr<<" ("<<key<<") msg:"<<forwardInfo->message->getJSONString();
+        prod->pushMsgAsync(*forwardInfo->message.get(),key);
+
+    } catch(CException& ex){
+        //in this case i need to delete the memory
+        //in this case i need to delete te memory allocated by message
+        DECODE_CHAOS_EXCEPTION(ex)
+    }
+    return true;
+}
+
+//-----timer handler------
+void PSMClient::timeout() {
+   
+}
+
+
+
+uint64_t PSMClient::getMessageQueueSize() {
+    return 0;
+}
diff --git a/chaos/common/rpc/psm/PSMClient.h b/chaos/common/rpc/psm/PSMClient.h
new file mode 100644
index 0000000000000000000000000000000000000000..ce9bfed4d3905771703f72ff313d48760679e50c
--- /dev/null
+++ b/chaos/common/rpc/psm/PSMClient.h
@@ -0,0 +1,92 @@
+//
+//  PSMClient.h
+//  CHAOSFramework
+//
+//  Created by Bisegni Claudio on 11/03/12.
+//  Copyright (c) 2012 INFN. All rights reserved.
+//
+
+#ifndef CHAOSFramework_PSMClient_h
+#define CHAOSFramework_PSMClient_h
+
+//#pragma GCC diagnostic ignored "-Woverloaded-virtual"
+
+#include <chaos/common/rpc/RpcClient.h>
+#include <chaos/common/pqueue/ChaosProcessingQueue.h>
+#include <chaos/common/utility/ObjectFactoryRegister.h>
+#include <chaos/common/utility/TimingUtil.h>
+#include <chaos/common/pool/ResourcePool.h>
+
+#include <boost/thread.hpp>
+#include <boost/shared_ptr.hpp>
+#include <chaos/common/message/MessagePSDriver.h>
+#include <map>
+#include <deque>
+namespace chaos {
+    
+    class PSMClient;
+    class SocketEndpointPool;
+    
+    struct PSMSocketPoolDef{
+        void * socket;
+        std::string identity;
+    };
+    
+    typedef chaos::common::pool::ResourcePool<PSMSocketPoolDef> PSMSocketPool;
+    
+    //define the pool my for every endpoint
+    CHAOS_DEFINE_MAP_FOR_TYPE(std::string, ChaosSharedPtr< PSMSocketPool >, SocketMap)
+    
+    /*
+     Class that implemnt !CHAOS RPC messaggin gusing PSM
+     
+     driver parameter:
+     key:zmq_timeout value is a stirng that represent the integer used as timeout
+     */
+    DECLARE_CLASS_FACTORY(PSMClient, RpcClient),
+    public chaos::common::async_central::TimerHandler {
+        REGISTER_AND_DEFINE_DERIVED_CLASS_FACTORY_HELPER(PSMClient)
+        PSMClient(const std::string& alias);
+        virtual ~PSMClient();
+        boost::shared_mutex map_socket_mutex;
+        ChaosAtomic<uint64_t> seq_id;
+        std::string nodeuid;
+    protected:        
+        //timer handler
+        void timeout();
+        
+        // publish subscribe
+		chaos::common::message::producer_uptr_t prod;
+    public:
+        
+        /*
+         init the rpc adapter
+         */
+        void init(void *init_data);
+        
+        /*
+         start the rpc adapter
+         */
+        void start();
+        
+        /*
+         start the rpc adapter
+         */
+        void stop();
+        
+        /*
+         deinit the rpc adapter
+         */
+        void deinit();
+        
+        /*
+         Submit the message to be send to a certain ip, the datawrapper must contains
+         the key CS_CMDM_REMOTE_HOST_IP
+         */
+        bool submitMessage(NFISharedPtr forwardInfo, bool onThisThread=false);
+        
+        //inherited method
+        virtual uint64_t getMessageQueueSize();
+    };
+}
+#endif
diff --git a/chaos/common/rpc/psm/PSMServer.cpp b/chaos/common/rpc/psm/PSMServer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2bb42d2b4421f4b8b2e95dc5e7664a65b7dc4796
--- /dev/null
+++ b/chaos/common/rpc/psm/PSMServer.cpp
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2012, 2017 INFN
+ *
+ * Licensed under the EUPL, Version 1.2 or – as soon they
+ * will be approved by the European Commission - subsequent
+ * versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the
+ * Licence.
+ * You may obtain a copy of the Licence at:
+ *
+ * https://joinup.ec.europa.eu/software/page/eupl
+ *
+ * Unless required by applicable law or agreed to in
+ * writing, software distributed under the Licence is
+ * distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied.
+ * See the Licence for the specific language governing
+ * permissions and limitations under the Licence.
+ */
+
+#include <chaos/common/global.h>
+#include <chaos/common/rpc/ChaosRpc.h>
+#include <chaos/common/chaos_constants.h>
+#include <chaos/common/exception/exception.h>
+#include <chaos/common/data/CDataWrapper.h>
+#include <chaos/common/rpc/RpcServerHandler.h>
+#define PSMS_LAPP INFO_LOG(PSMServer)
+#define PSMS_LDBG DBG_LOG(PSMServer)
+#define PSMS_LERR ERR_LOG(PSMServer)
+
+using namespace std;
+using namespace chaos;
+using namespace boost;
+using namespace chaos::common::data;
+#include "PSMServer.h"
+
+DEFINE_CLASS_FACTORY(PSMServer, RpcServer);
+PSMServer::PSMServer(const string& alias):
+RpcServer(alias){
+    is_psm=true;
+    
+}
+
+PSMServer::~PSMServer() {
+    
+}
+
+//init the server getting the configuration value
+void PSMServer::init(void *init_data) {
+    CDataWrapper *cfg = reinterpret_cast<CDataWrapper*>(init_data);
+    PSMS_LAPP << "initialization";
+   try{
+    if(!cfg->hasKey(InitOption::OPT_MSG_BROKER_SERVER)){
+        throw chaos::CException(-1, "a not empty broker must be given", __PRETTY_FUNCTION__);
+    }
+    if(!cfg->hasKey(chaos::InitOption::OPT_NODEUID)){
+      throw chaos::CException(-1, "a not empty and unique id must be given", __PRETTY_FUNCTION__);
+    }
+    nodeuid      = cfg->getStringValue(chaos::InitOption::OPT_NODEUID);
+    std::string msgbrokerdrv = "kafka-rdk";
+    if(cfg->hasKey(InitOption::OPT_MSG_BROKER_DRIVER)){
+        msgbrokerdrv     = cfg->getStringValue(chaos::InitOption::OPT_MSG_BROKER_DRIVER);
+
+    }
+    
+    std::string msgbroker = cfg->getStringValue(InitOption::OPT_MSG_BROKER_SERVER);
+    std::string gname;
+    if(cfg->hasKey(InitOption::OPT_GROUP_NAME)){
+        gname=cfg->getStringValue(InitOption::OPT_GROUP_NAME);
+        PSMS_LAPP << "belong to group:\""<<gname<<"\"";
+
+    } else {
+        gname=nodeuid;
+    }
+
+    cons = chaos::common::message::MessagePSDriver::getNewConsumerDriver(msgbrokerdrv, gname);
+    prod = chaos::common::message::MessagePSDriver::getProducerDriver(msgbrokerdrv);
+
+    if (cons.get() == 0) {
+      throw chaos::CException(-3, "cannot initialize Publish Subscribe Consumer of topic:" + nodeuid + "_cmd", __PRETTY_FUNCTION__);
+    }
+    cons->addServer(msgbroker);
+    prod->addServer(msgbroker);
+    // subscribe to the queue of commands
+    cons->addHandler(chaos::common::message::MessagePublishSubscribeBase::ONARRIVE, boost::bind(&PSMServer::messageHandler, this, _1));
+    cons->addHandler(chaos::common::message::MessagePublishSubscribeBase::ONERROR, boost::bind(&PSMServer::messageError, this, _1));
+    if (cons->applyConfiguration() != 0) {
+        throw chaos::CException(-1, "cannot initialize Publish Subscribe:" + cons->getLastError(), __PRETTY_FUNCTION__);
+    }
+    if(cfg->hasKey("ismds")){
+        PSMS_LAPP << "Subscribing to " <<chaos::common::constants::CHAOS_ADMIN_ADMIN_TOPIC;
+        cons->subscribe(chaos::common::constants::CHAOS_ADMIN_ADMIN_TOPIC);
+    }
+    } catch (std::exception& e) {
+        throw CException(-2, e.what(), "PSMServer::init");
+    } catch (...) {
+        throw CException(-3, "generic error", "PSMServer::init");
+    }
+}
+void PSMServer::messageHandler( chaos::common::message::ele_t& data) {
+    int64_t seq_id=-1;
+    std::string src;
+    //chaos::common::data::CDWUniquePtr data(d.cd.release());
+    if(data.cd->hasKey(RPC_SEQ_KEY)){
+        seq_id=data.cd->getInt64Value(RPC_SEQ_KEY);
+    }
+    if(data.cd->hasKey(RpcActionDefinitionKey::CS_CMDM_ANSWER_HOST_IP)){
+        src=data.cd->getStringValue(RPC_SRC_UID);
+    }
+    PSMS_LDBG << "Message Received from node:"<<src<<" seq_id:"<<seq_id << " desc:"<<data.cd->getJSONString();
+    CDWShrdPtr result_data_pack;
+
+    if(data.cd->hasKey(RPC_SYNC_KEY) &&
+        data.cd->getBoolValue(RPC_SYNC_KEY)) {
+        
+        result_data_pack = command_handler->executeCommandSync(MOVE(data.cd));
+    } else {
+        result_data_pack = command_handler->dispatchCommand(MOVE(data.cd));
+    }
+
+    if(result_data_pack.get() && src.size()){
+        PSMS_LDBG << "Something to send back:"<<seq_id << "to node:"<<src<<" desc:"<<result_data_pack->getJSONString();
+        prod->pushMsgAsync(*result_data_pack.get(),src);
+    }
+                    
+}
+void PSMServer::messageError( chaos::common::message::ele_t& data) {
+        PSMS_LERR  << "ERROR:";
+
+}
+ std::string PSMServer::getPublishedEndpoint(){
+    
+    return nodeuid + chaos::DataPackPrefixID::COMMAND_DATASET_POSTFIX;
+}
+//start the rpc adapter
+void PSMServer::start() {
+  
+    PSMS_LAPP << "Subscribing to " << nodeuid + chaos::DataPackPrefixID::COMMAND_DATASET_POSTFIX;
+    cons->subscribe(nodeuid + chaos::DataPackPrefixID::COMMAND_DATASET_POSTFIX);
+    cons->start();
+    prod->start();
+}
+
+//start the rpc adapter
+void PSMServer::stop() {
+    cons->stop();
+    
+}
+
+//deinit the rpc adapter
+void PSMServer::deinit() {
+    
+    PSMS_LAPP << "PSMServer deinit";
+}
diff --git a/chaos/common/rpc/psm/PSMServer.h b/chaos/common/rpc/psm/PSMServer.h
new file mode 100644
index 0000000000000000000000000000000000000000..62be49e73af0a376fcc0270ce320fd732f0e9b2a
--- /dev/null
+++ b/chaos/common/rpc/psm/PSMServer.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2012, 2017 INFN
+ *
+ * Licensed under the EUPL, Version 1.2 or – as soon they
+ * will be approved by the European Commission - subsequent
+ * versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the
+ * Licence.
+ * You may obtain a copy of the Licence at:
+ *
+ * https://joinup.ec.europa.eu/software/page/eupl
+ *
+ * Unless required by applicable law or agreed to in
+ * writing, software distributed under the Licence is
+ * distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied.
+ * See the Licence for the specific language governing
+ * permissions and limitations under the Licence.
+ */
+
+#ifndef CHAOSFramework_PSMServer_h
+#define CHAOSFramework_PSMServer_h
+//#pragma GCC diagnostic ignored "-Woverloaded-virtual"
+
+#include <vector>
+#include <boost/thread.hpp>
+#include <chaos/common/message/MessagePSDriver.h>
+
+#include <chaos/common/rpc/RpcServer.h>
+#include <chaos/common/utility/ObjectFactoryRegister.h>
+
+
+namespace chaos {
+    /*
+     Class that implement the Chaos RPC adapter for 0mq protocoll
+     */
+    DECLARE_CLASS_FACTORY(PSMServer, RpcServer)  {
+        REGISTER_AND_DEFINE_DERIVED_CLASS_FACTORY_HELPER(PSMServer)
+        // publish subscribe
+		chaos::common::message::consumer_uptr_t cons;
+        chaos::common::message::producer_uptr_t prod;
+
+        std::string nodeuid;
+        PSMServer(const std::string& alias);
+        virtual ~PSMServer();
+        //worker that process request in a separate thread
+        void messageHandler( chaos::common::message::ele_t& data);
+        void messageError( chaos::common::message::ele_t& data);
+
+    public:
+        
+        /*
+         init the rpc adapter
+         */
+        void init(void *init_data);
+        /*
+         start the rpc adapter
+         */
+        void start();
+        /*
+         start the rpc adapter
+         */
+        void stop();
+        /*
+         deinit the rpc adapter
+         */
+        void deinit();
+        
+        //server worker thread
+        /*!
+         Thread where data is received and managed
+         */
+        std::string getPublishedEndpoint();
+            };
+    
+}
+#endif
diff --git a/chaos/cu_toolkit/ChaosCUToolkit.cpp b/chaos/cu_toolkit/ChaosCUToolkit.cpp
index f8e3e92d15b05891bbba9dce9c507ff08bea27eb..0fd2e4c0b40bc99780716a6c2567e0bed9fa8c60 100644
--- a/chaos/cu_toolkit/ChaosCUToolkit.cpp
+++ b/chaos/cu_toolkit/ChaosCUToolkit.cpp
@@ -132,8 +132,9 @@ void ChaosCUToolkit::init(void* init_data) {
     InizializableService::initImplementation(SharedManagedDirecIoDataDriver::getInstance(), NULL, "SharedManagedDirecIoDataDriver", __PRETTY_FUNCTION__);
 
     if (GlobalConfiguration::getInstance()->hasOption(InitOption::OPT_LOG_ON_MDS) &&
-        GlobalConfiguration::getInstance()->hasOption(InitOption::CONTROL_MANAGER_UNIT_SERVER_ALIAS)) {
-      chaos::common::log::LogManager::getInstance()->addMDSLoggingBackend(GlobalConfiguration::getInstance()->getOption<std::string>(InitOption::CONTROL_MANAGER_UNIT_SERVER_ALIAS));
+        GlobalConfiguration::getInstance()->hasOption(InitOption::OPT_NODEUID)) {
+        nodeuid=GlobalConfiguration::getInstance()->getNodeUID();
+      chaos::common::log::LogManager::getInstance()->addMDSLoggingBackend(nodeuid);
     }
 
     //force first allocation of metadata logging
@@ -179,7 +180,7 @@ void ChaosCUToolkit::start() {
     StartableService::startImplementation(ControlManager::getInstance(), "ControlManager", "ChaosCUToolkit::start");
     LAPP_ << "-----------------------------------------";
     LAPP_ << "!CHAOS Control Unit System Started";
-    LAPP_ << "RPC Server address: " << CommandManager::getInstance()->broker->getRPCUrl();
+    LAPP_ << "Server Endpoint: " << CommandManager::getInstance()->broker->getRPCUrl();
     LAPP_ << "DirectIO Server address: " << CommandManager::getInstance()->broker->getDirectIOUrl();
     LAPP_ << "-----------------------------------------";
     //at this point i must with for end signal
diff --git a/chaos/cu_toolkit/control_manager/AbstractControlUnit.cpp b/chaos/cu_toolkit/control_manager/AbstractControlUnit.cpp
index a7f1dd6fc634aae18b44507a6bbabb68512ab1ba..ba39fce54e2013faac321d8d8c635842256fb24b 100644
--- a/chaos/cu_toolkit/control_manager/AbstractControlUnit.cpp
+++ b/chaos/cu_toolkit/control_manager/AbstractControlUnit.cpp
@@ -34,6 +34,7 @@
 #include <boost/uuid/uuid.hpp>             // uuid class
 #include <boost/uuid/uuid_generators.hpp>  // generators
 #include <boost/uuid/uuid_io.hpp>          // streaming operators etc.
+#include <boost/filesystem.hpp>
 
 #include "../windowsCompliant.h"
 using namespace boost::uuids;
@@ -136,6 +137,7 @@ AbstractControlUnit::AbstractControlUnit(const std::string& _control_unit_type,
     , standard_logging_channel()
     , alarm_logging_channel()
     , push_dataset_counter(0)
+    , aligned_ex_done(false)
     , push_dataset_size(0)
     , push_tot_size(0)
     , last_push_rate_grap_ts(0)
@@ -180,6 +182,7 @@ AbstractControlUnit::AbstractControlUnit(const std::string&           _control_u
     , standard_logging_channel()
     , alarm_logging_channel()
     , push_dataset_counter(0)
+    , aligned_ex_done(false)
     , push_errors(0)
     , packet_lost(0)
     , last_push_rate_grap_ts(0)
@@ -458,9 +461,20 @@ void AbstractControlUnit::_defineActionAndDataset(CDataWrapper& setup_configurat
   PropertyCollector::fillDescription("property", setup_configuration);
 }
 chaos::common::data::CDWUniquePtr AbstractControlUnit::getProperty(chaos::common::data::CDWUniquePtr data) {
-  chaos::common::data::CDWUniquePtr ret = getProperties();
-  ACULDBG_ << "get CU properties:" << ((ret.get()) ? ret->getJSONString() : "");
+  bool sync=true;
+   chaos::common::data::CDWUniquePtr ret ;
+  if(data.get()&&data->hasKey("sync")){
+    sync=data->getBoolValue("sync");
+  }
+  if(data.get()&&data->hasKey("name")){
+    std::string name=data->getStringValue("name");
+    ret=syncRead(name);
+    ACULDBG_ << "get CU property :" <<name<<" ="<< ((ret.get()) ? ret->getJSONString() : "");
 
+    return ret;
+  }
+  ret= getProperties(sync);
+  ACULDBG_ << "get CU properties:" << ((ret.get()) ? ret->getJSONString() : "");
   return ret;
 }
 chaos::common::data::CDWUniquePtr AbstractControlUnit::setProperty(chaos::common::data::CDWUniquePtr data) {
@@ -485,6 +499,78 @@ void AbstractControlUnit::setAlarmMask(const std::string& name, uint32_t mask) {
     alarmv->setMask(mask);
   }
 }
+
+  int AbstractControlUnit::saveData(const std::string& keyname,const chaos::common::data::CDataWrapper& d){
+    std::string fname = control_unit_id;
+    replace(fname.begin(), fname.end(), '/', '_');
+    std::stringstream ss;
+    ss << "/tmp/"<<fname;
+    boost::filesystem::path p(ss.str());
+    if ((boost::filesystem::exists(p) == false)) {
+          try {
+            if ((boost::filesystem::create_directories(p) == false) && ((boost::filesystem::exists(p) == false))) {
+              ACULERR_ << "cannot create directory:" << p ;
+              return -3;
+            } else {
+              ACULDBG_ << " CREATED DIR:" << p;
+            }
+          } catch (boost::filesystem::filesystem_error& e) {
+            ACULERR_ << " Exception creating directory:" << e.what();
+            return -1;
+          }
+          //
+      }
+    ss<<"/"+keyname;
+    std::ofstream fs;
+    fs.open(ss.str().c_str());
+    if(!fs.is_open()){
+        ACULERR_ << " cannot create " << ss.str();
+        return -5;
+    }
+    fs<<d.getJSONString();
+
+    fs.close();
+    ACULDBG_ << keyname<<" wrote " <<ss.str()<<" size:"<<d.getJSONString().size();
+    getAttributeCache()->addCustomAttribute(keyname, d);
+    getAttributeCache()->setCustomAttributeValue(keyname, d);
+    fillCachedValueVector(attribute_value_shared_cache->getSharedDomain(DOMAIN_CUSTOM),
+                                  cache_custom_attribute_vector);
+    getAttributeCache()->setCustomDomainAsChanged();
+    pushCustomDataset();
+    return 0;
+  }
+  
+  chaos::common::data::CDWUniquePtr AbstractControlUnit::loadData(const std::string& keyname){
+    chaos::common::data::CDWUniquePtr ret;
+    std::string fname = control_unit_id;
+    replace(fname.begin(), fname.end(), '/', '_');
+    std::stringstream ss;
+    ss << "/tmp/"<<fname<<"/"+keyname;
+    std::ifstream fs;
+    fs.open(ss.str().c_str());
+    if(fs.is_open()){
+      std::stringstream buffer;
+      buffer << fs.rdbuf();
+      chaos::common::data::CDataWrapper*w=new chaos::common::data::CDataWrapper();
+      if(w){
+        try {
+          w->setSerializedJsonData(buffer.str().c_str());
+          ret.reset(w);
+        /*  getAttributeCache()->addCustomAttribute(keyname, *w);
+          getAttributeCache()->setCustomAttributeValue(keyname, *w);
+
+          getAttributeCache()->setCustomDomainAsChanged();
+          pushCustomDataset();*/
+          ACULDBG_ << keyname<<" read: " <<ss.str()<<" size:"<<buffer.str().size();
+        } catch(...){
+            ACULERR_ << " parsing JSON " << buffer.str();
+
+        }
+      }
+
+    }
+    return ret;
+  }
 chaos::common::data::CDWUniquePtr AbstractControlUnit::clrAlarm(chaos::common::data::CDWUniquePtr data) {
   if (data.get()) {
     if (!data->hasKey("value")) {
@@ -1125,7 +1211,7 @@ void AbstractControlUnit::doInitSMCheckList() {
       //initialize key data storage for device id
       //ACULDBG_ << "Create KeyDataStorage device:" << DatasetDB::getDeviceID();
       key_data_storage.reset(DataManager::getInstance()->getKeyDataStorageNewInstanceForKey(DatasetDB::getDeviceID()));
-
+      aligned_ex_done=false;
       ACULDBG_ << "Call KeyDataStorage init implementation for deviceID:" << DatasetDB::getDeviceID() << " init:" << ((init_configuration.get()) ? init_configuration->getJSONString() : "NULL CONFIG");
       key_data_storage->init(init_configuration.get());
       break;
@@ -2245,7 +2331,7 @@ void AbstractControlUnit::completeInputAttribute() {
 AbstractSharedDomainCache* AbstractControlUnit::_getAttributeCache() {
   return attribute_value_shared_cache;
 }
-int AbstractControlUnit::incomingMessage(const std::string& key, const chaos::common::data::CDWShrdPtr& data) {
+int AbstractControlUnit::incomingMessage(const std::string& key,  chaos::common::data::CDWUniquePtr& data) {
   ACULDBG_ << "message from :" << key << " data:" << (data.get() ? data->getJSONString() : "NONE");
   return 0;
 }
@@ -2836,8 +2922,9 @@ int AbstractControlUnit::pushOutputDataset() {
       return err;
     }
   }
-  if(push_dataset_counter==1){
+  if((aligned_ex_done==false)&&(push_dataset_counter==1)){
     dsInitSetFromReadout();
+    aligned_ex_done=true;
   }
   last_push                           = tscor;
   CDWShrdPtr output_attribute_dataset = key_data_storage->getNewDataPackForDomain(KeyDataStorageDomainOutput);
@@ -3360,7 +3447,7 @@ void AbstractControlUnit::metadataLogging(const StandardLoggingChannel::LogLevel
                   message);
 }
 
-void AbstractControlUnit::consumerHandler(const chaos::common::message::ele_t& data) {
+void AbstractControlUnit::consumerHandler( chaos::common::message::ele_t& data) {
   incomingMessage(data.key, data.cd);
 }
 void AbstractControlUnit::updateDataSet(chaos::common::data::CDataWrapper& cd, chaos::DataType::DataSetAttributeIOAttribute io) {
diff --git a/chaos/cu_toolkit/control_manager/AbstractControlUnit.h b/chaos/cu_toolkit/control_manager/AbstractControlUnit.h
index 0b3b4fb9d3c93af728988b26462c0d7e80c5b470..77b319dd0cc3268ebc469a2c15f81437857502ac 100644
--- a/chaos/cu_toolkit/control_manager/AbstractControlUnit.h
+++ b/chaos/cu_toolkit/control_manager/AbstractControlUnit.h
@@ -335,7 +335,7 @@ class AbstractControlUnit : public DeclareAction,
   AttributeSharedCacheWrapper* attribute_shared_cache_wrapper;
 
   //! fast access for acquisition timestamp
-  bool            use_custom_high_resolution_timestamp;
+  bool            use_custom_high_resolution_timestamp,aligned_ex_done;
   AttributeValue* timestamp_acq_cached_value;
   AttributeValue* timestamp_hw_acq_cached_value;
 
@@ -409,6 +409,7 @@ class AbstractControlUnit : public DeclareAction,
 
   // Startable Service method
   void deinit();
+  
 
   //! State machine is gone into recoverable error
   void recoverableErrorFromState(int last_state, chaos::CException& ex);
@@ -561,7 +562,7 @@ class AbstractControlUnit : public DeclareAction,
   void _setBypassState(bool bypass_stage,
                        bool high_priority = false);
 
-  virtual void consumerHandler(const chaos::common::message::ele_t& data);
+  virtual void consumerHandler( chaos::common::message::ele_t& data);
 
   template <typename T>
   bool _setDrvProp(const std::string& name, const T& value, uint32_t size,bool bi) {
@@ -727,7 +728,7 @@ class AbstractControlUnit : public DeclareAction,
    * @param data pack
    * @return int return 0 if succefully handled
    */
-  virtual int incomingMessage(const std::string& key, const chaos::common::data::CDWShrdPtr& data);
+  virtual int incomingMessage(const std::string& key,  chaos::common::data::CDWUniquePtr& data);
 
   //!callback for put a veto on property value change request
   virtual bool propertyChangeHandler(const std::string&                       group_name,
@@ -922,7 +923,22 @@ class AbstractControlUnit : public DeclareAction,
   void addAttributesToDataSet(chaos::common::data::CDataWrapper&cd,chaos::DataType::DataSetAttributeIOAttribute io=chaos::DataType::Output);
   void updateDataSet(chaos::common::data::CDataWrapper&cd,chaos::DataType::DataSetAttributeIOAttribute io=chaos::DataType::Output);
   
-
+/**
+   * @brief Save custom (configuration) Data as keyname
+   * 
+   * @param keyname 
+   * @param d data
+   * @return int 0 on success;
+   */
+  int saveData(const std::string& keyname,const chaos::common::data::CDataWrapper& d);
+  /**
+   * @brief Load  custom (configuration) Data 
+   * 
+   * @param keyname 
+   * @param d data
+   * @return int 0 on success;
+   */
+  chaos::common::data::CDWUniquePtr loadData(const std::string& keyname);
   CUStateKey::ControlUnitState getState();
   bool                         removeHandlerOnAttributeName(const std::string& attribute_name) {
     return dataset_attribute_manager.removeHandlerOnAttributeName(attribute_name);
diff --git a/chaos/cu_toolkit/control_manager/ControlManager.cpp b/chaos/cu_toolkit/control_manager/ControlManager.cpp
index b131d7158f29fe8b1bb3795869572347ec117345..68bdf54314f5a4cf4f3c86674a80e80b50b3639a 100644
--- a/chaos/cu_toolkit/control_manager/ControlManager.cpp
+++ b/chaos/cu_toolkit/control_manager/ControlManager.cpp
@@ -58,7 +58,7 @@ using namespace std;
  Constructor
  */
 ControlManager::ControlManager()
-    : publishing_counter_delay(0), use_unit_server(false), use_execution_pools(false), thread_run(false), mds_channel(NULL) {
+    : publishing_counter_delay(0), use_execution_pools(false), thread_run(false), mds_channel(NULL) {
   //! register default control unit
   registerControlUnit<chaos::cu::control_manager::ProxyControlUnit>();
   registerControlUnit<chaos::cu::control_manager::script::ScriptableExecutionUnit>();
@@ -77,9 +77,6 @@ void ControlManager::init(void* initParameter) {
   //control manager action initialization
   AbstActionDescShrPtr actionDescription;
 
-  //check if we need to start the unit server
-  use_unit_server = GlobalConfiguration::getInstance()->hasOption(InitOption::CONTROL_MANAGER_UNIT_SERVER_ALIAS);
-
   //check for execution pools
   use_execution_pools = GlobalConfiguration::getInstance()->hasOption(CONTROL_MANAGER_EXECUTION_POOLS);
 
@@ -90,11 +87,11 @@ void ControlManager::init(void* initParameter) {
   else
     throw CException(-2, "Error allcoating metadata server channel", __PRETTY_FUNCTION__);
 
-  if (use_unit_server) {
+  {
     LCMAPP_ << "Enable unit server";
 
-    if (!GlobalConfiguration::getInstance()->hasOption(InitOption::CONTROL_MANAGER_UNIT_SERVER_ALIAS)) {
-      throw CException(-1, "No server alias param found", __PRETTY_FUNCTION__);
+    if (!GlobalConfiguration::getInstance()->hasOption(InitOption::OPT_NODEUID)) {
+      throw CException(-1, "No required "+std::string(InitOption::OPT_NODEUID)+" option given", __PRETTY_FUNCTION__);
     }
 
     if (GlobalConfiguration::getInstance()->hasOption(CONTROL_MANAGER_UNIT_SERVER_KEY)) {
@@ -115,7 +112,7 @@ void ControlManager::init(void* initParameter) {
       }
     }
 
-    unit_server_alias = GlobalConfiguration::getInstance()->getOption<std::string>(InitOption::CONTROL_MANAGER_UNIT_SERVER_ALIAS);
+    unit_server_alias = GlobalConfiguration::getInstance()->getNodeUID();
 
     //init CU action
     actionDescription = DeclareAction::addActionDescritionInstance<ControlManager>(this,
@@ -179,14 +176,11 @@ void ControlManager::init(void* initParameter) {
 void ControlManager::start() {
   LCMAPP_ << "Start cu scan timer";
   int err = 0;
-  if (use_unit_server) {
     //add unit server registration managment timer
-    if ((err = chaos_async::AsyncCentralManager::getInstance()->addTimer(this, 0, GlobalConfiguration::getInstance()->getOption<uint64_t>(CONTROL_MANAGER_UNIT_SERVER_REGISTRATION_RETRY_MSEC)))) {
-      throw chaos::CException(-1, "Error registering the Control managet timer", __PRETTY_FUNCTION__);
-    }
-  } else {
-    startControlUnitSMThread();
+  if ((err = chaos_async::AsyncCentralManager::getInstance()->addTimer(this, 0, GlobalConfiguration::getInstance()->getOption<uint64_t>(CONTROL_MANAGER_UNIT_SERVER_REGISTRATION_RETRY_MSEC)))) {
+    throw chaos::CException(-1, "Error registering the Control managet timer", __PRETTY_FUNCTION__);
   }
+
 }
 
 // start control units state machine thread
@@ -688,17 +682,13 @@ void ControlManager::timeout() {
       //Unpublished
     case 0:
       LCMAPP_ << "[Unpublished] Send first registration pack to mds";
-      if (use_unit_server) {
-        if (unit_server_sm.process_event(unit_server_state_machine::UnitServerEventType::UnitServerEventTypePublishing()) == boost::msm::back::HANDLED_TRUE) {
-          //gone to publishing
-          sendUnitServerRegistration();
-        } else {
-          LCMERR_ << "[Unpublished] i can't be here";
-        }
+      if (unit_server_sm.process_event(unit_server_state_machine::UnitServerEventType::UnitServerEventTypePublishing()) == boost::msm::back::HANDLED_TRUE) {
+        //gone to publishing
+        sendUnitServerRegistration();
       } else {
-        LCMDBG_ << "[Publishing] Unit server registration not sucessfull, turn off the timer";
-        TimerHandler::stopMe();
+        LCMERR_ << "[Unpublished] i can't be here";
       }
+     
       break;
       //Publishing
     case 1:
@@ -720,7 +710,6 @@ void ControlManager::timeout() {
     case 3:
       LCMAPP_ << "[Published failed] Perform Unpublishing state";
       TimerHandler::stopMe();
-      use_unit_server = false;
       break;
   }
 }
diff --git a/chaos/cu_toolkit/control_manager/ControlManager.h b/chaos/cu_toolkit/control_manager/ControlManager.h
index d1bf27221ae9bbca51eee0de84599d9497c42d80..5de740c07c46a4f6ddaee7c65dfff79865529075 100644
--- a/chaos/cu_toolkit/control_manager/ControlManager.h
+++ b/chaos/cu_toolkit/control_manager/ControlManager.h
@@ -133,7 +133,6 @@ namespace chaos {
 				//mutable boost::shared_mutex mutex_registration;
 				
 				//unit server state machine
-				bool					use_unit_server;
                 bool                    use_execution_pools;
                 unsigned int            publishing_counter_delay;
                 
diff --git a/chaos/cu_toolkit/control_manager/control_manager_constants.h b/chaos/cu_toolkit/control_manager/control_manager_constants.h
index 937349417acb6b58f2225a9437e02eb3c8f3813c..a9d8d3d204992a15b54a455a55f672228d5b624a 100644
--- a/chaos/cu_toolkit/control_manager/control_manager_constants.h
+++ b/chaos/cu_toolkit/control_manager/control_manager_constants.h
@@ -31,7 +31,6 @@ namespace chaos {
 #define CONTROL_MANAGER_UNIT_SERVER_ENABLE							"unit-server-enable"
 #define CONTROL_MANAGER_UNIT_SERVER_ENABLE_desc						"Enable the unit server on this instance of process"
             
-//#define CONTROL_MANAGER_UNIT_SERVER_ALIAS							"unit-server-alias"
 #define CONTROL_MANAGER_UNIT_SERVER_ALIAS_desc						"Alias used to publish the unit server"
 #define CONTROL_MANAGER_UNIT_SERVER_KEY								"unit-server-file-key"
 #define CONTROL_MANAGER_UNIT_SERVER_KEY_desc						"the path to the file that contains the rsa public key for the unit server alias"
diff --git a/chaos/cu_toolkit/control_manager/execution_pool/ExecutionPool.cpp b/chaos/cu_toolkit/control_manager/execution_pool/ExecutionPool.cpp
index d18cc4cafea318166df1a85bf47dfb00502674dd..060d7daf4fcc3de2a90913b7daf39704a757a765 100644
--- a/chaos/cu_toolkit/control_manager/execution_pool/ExecutionPool.cpp
+++ b/chaos/cu_toolkit/control_manager/execution_pool/ExecutionPool.cpp
@@ -48,8 +48,8 @@ ExecutionPoolManager::~ExecutionPoolManager() {}
 
 void ExecutionPoolManager::init(void *init_data)  {
     int err = 0;
-    if(GlobalConfiguration::getInstance()->hasOption(InitOption::CONTROL_MANAGER_UNIT_SERVER_ALIAS)){
-        unit_server_alias = GlobalConfiguration::getInstance()->getOption<std::string>(InitOption::CONTROL_MANAGER_UNIT_SERVER_ALIAS);
+    if(GlobalConfiguration::getInstance()->hasOption(InitOption::OPT_NODEUID)){
+        unit_server_alias = GlobalConfiguration::getInstance()->getNodeUID();
     }
     execution_pool_list = GlobalConfiguration::getInstance()->getOption< std::vector<std::string> >(CONTROL_MANAGER_EXECUTION_POOLS);
     
diff --git a/chaos_service_common/ChaosManager.cpp b/chaos_service_common/ChaosManager.cpp
index 03eaf4b08d993ec32befce91b87f90ff300bf290..18065b55412228f5c7240b1c4a4dcc5be2f469e6 100644
--- a/chaos_service_common/ChaosManager.cpp
+++ b/chaos_service_common/ChaosManager.cpp
@@ -5,6 +5,7 @@
  * Created on 21/04/2021
  */
 #include "ChaosManager.h"
+#include <ChaosMetadataService/ChaosMetadataService.h>
 #include <chaos/common/message/MDSMessageChannel.h>
 #include <ChaosMetadataService/api/node/ClearCommandQueue.h>
 #include <ChaosMetadataService/api/node/CommandTemplateSubmit.h>
@@ -93,7 +94,9 @@ using namespace chaos::metadata_service::api::service;
 CDWShrdPtr ChaosManager::getLiveChannel(const std::string& key) {
   ChaosSharedPtr<chaos::common::data::CDataWrapper> ret;
   if (cache_driver) {
-    return cache_driver->getData(key);
+    ret=cache_driver->getData(key);
+    context->updateLiveCache(ret.get());
+    return ret;
   }
   return ret;
 }
@@ -103,7 +106,9 @@ CDWShrdPtr ChaosManager::getLiveChannel(const std::string& key, int domain) {
   std::string                                       lkey = key + chaos::datasetTypeToPostfix(domain);
   char*                                             value;
   if (cache_driver) {
-    return cache_driver->getData(key);
+    ret=cache_driver->getData(key);
+    context->updateLiveCache(ret.get());
+    return ret;
   }
   return ret;
 }
@@ -112,10 +117,14 @@ ChaosManager::ChaosManager(const chaos::common::data::CDataWrapper& conf)
   if (init(conf) != 0) {
     throw chaos::CException(-1, "Cannot initialize ", __PRETTY_FUNCTION__);
   }
+  context= chaos::metadata_service::ChaosMetadataService::getInstance();
+
 }
 ChaosManager::ChaosManager()
     : cache_driver(NULL), persistence_driver(NULL),storage_driver(NULL) {
   chaos::common::message::MDSMessageChannel* mdsChannel = chaos::common::network::NetworkBroker::getInstance()->getMetadataserverMessageChannel();
+  context= chaos::metadata_service::ChaosMetadataService::getInstance();
+
   if (mdsChannel) {
     CDWUniquePtr best_available_da_ptr;
     if (!mdsChannel->getDataDriverBestConfiguration(best_available_da_ptr, 5000)) {
@@ -197,7 +206,7 @@ int ChaosManager::init(const chaos::common::data::CDataWrapper& best_available_d
     InizializableService::initImplementation(DriverPoolManager::getInstance(), NULL, "DriverPoolManager", __PRETTY_FUNCTION__);
     
     } catch(...){
-            DBGETERR << "Error Initializing";
+            DBGETERR << "Error Initializing alla drivers";
 
     }
 
@@ -218,19 +227,30 @@ int ChaosManager::init(const chaos::common::data::CDataWrapper& best_available_d
     }
     StartableService::initImplementation(MDSBatchExecutor::getInstance(), NULL, "MDSBatchExecutor", __PRETTY_FUNCTION__);
     StartableService::startImplementation(MDSBatchExecutor::getInstance(), "MDSBatchExecutor", __PRETTY_FUNCTION__);
-    storage_driver = DriverPoolManager::getInstance()->getObjectStorageDrvPtr();
+    try {
+      storage_driver = NULL;
+      storage_driver = DriverPoolManager::getInstance()->getObjectStorageDrvPtr();
+    } catch(chaos::CException& e){
+            DBGETERR << "Exception during initialization of storage driver:"<<e.what();
+    } catch(...){
+          DBGETERR << "Undefined Exception during initialization of storage driver:";
+
+    }
     if (storage_driver == NULL) {
       DBGETERR << "Cannot use direct storage driver";
-      return -2;
-
     } else {
       DBGET << "Using direct storage driver";
     }
-
+  try{
     log_driver = DriverPoolManager::getInstance()->getLogDrvPtr();
+  } catch(chaos::CException& e){
+            DBGETERR << "Exception during initialization of log driver:"<<e.what();
+    } catch(...){
+          DBGETERR << "Undefined Exception during initialization of log driver:";
+
+    }
     if (log_driver == NULL) {
       DBGETERR << "Cannot use log direct driver";
-      return -2;
 
     } else {
       DBGET << "Using log direct driver";
@@ -287,6 +307,9 @@ chaos::common::data::VectorCDWShrdPtr ChaosManager::getLiveChannel(const std::ve
   chaos::common::data::VectorCDWShrdPtr results;
   if (cache_driver) {
     results = cache_driver->getData(channels);
+    for(int cnt=0;cnt<results.size();cnt++){
+      context->updateLiveCache(results[cnt].get());
+    }
     return results;
   }
   return results;
@@ -1088,6 +1111,15 @@ CDWUniquePtr ChaosManager::cuGetFullDescription(const std::string& uid) {
   }
   return res;
 }
+int ChaosManager::enableLiveCaching(const std::string key,int32_t duration_ms){
+  if (cache_driver) {
+    cache_driver->enableCache(key,duration_ms);
+
+    return 0;
+  }
+  return -1;
+  
+}
 int ChaosManager::nodeSearch(const std::string&              unique_id_filter,
                              chaos::NodeType::NodeSearchType node_type_filter,
                              bool                            alive_only,
diff --git a/chaos_service_common/ChaosManager.h b/chaos_service_common/ChaosManager.h
index 76d55ddbdc8c0800f1c0caea4d64b36f8ae58b84..93dda4483d72f88b23b1d8d067e456287670ae28 100644
--- a/chaos_service_common/ChaosManager.h
+++ b/chaos_service_common/ChaosManager.h
@@ -17,6 +17,9 @@
 #include <chaos/common/batch_command/BatchCommandTypes.h>
 #define DEFAULT_TIMEOUT_FOR_CONTROLLER 10000000
 namespace chaos {
+  namespace metadata_service{
+    class ChaosMetadataService;
+  }
 namespace common {
 namespace cache_system {
 class CacheDriver;
@@ -38,7 +41,7 @@ class ChaosManager : public chaos::common::utility::SingletonCW<ChaosManager>{
   chaos::service_common::persistence::data_access::AbstractPersistenceDriver* storage_driver;
     chaos::service_common::persistence::data_access::AbstractPersistenceDriver* log_driver;
 
-
+  chaos::metadata_service::ChaosMetadataService* context;
   //  ::common::misc::data::DBbase* db;
   // NetworkBroker *broker;
   //chaos::common::message::MDSMessageChannel *mdsChannel;
@@ -125,6 +128,7 @@ chaos::common::data::CDWUniquePtr checkAgentHostedProcess(const std::string&name
 
 chaos::common::data::CDWUniquePtr clearCommandQueue(const std::string&name);
 chaos::common::data::CDWUniquePtr killCurrentCommand(const std::string&name);
+int enableLiveCaching(const std::string key,int32_t duration_ms);
 
 };
 }  // namespace service_common
diff --git a/chaos_service_common/DriverPoolManager.cpp b/chaos_service_common/DriverPoolManager.cpp
index c3ad4719357cd633d0c3c2dccb6b69a8baa697e7..86b528b280f22e9849500c94eec663b1656d0e8b 100644
--- a/chaos_service_common/DriverPoolManager.cpp
+++ b/chaos_service_common/DriverPoolManager.cpp
@@ -25,11 +25,11 @@
 #include "cache_system/CacheDriverMetricCollector.h"
 #endif
 
-#include <limits>
 #include <chaos/common/global.h>
 #include <chaos/common/utility/ObjectFactoryRegister.h>
+#include <limits>
 #define DP_LOG_INFO INFO_LOG(DriverPoolManager)
-#define DP_LOG_DBG  DBG_LOG(DriverPoolManager)
+#define DP_LOG_DBG DBG_LOG(DriverPoolManager)
 #define DP_LOG_ERR ERR_LOG(DriverPoolManager)
 
 using namespace chaos::service_common;
@@ -41,90 +41,124 @@ using namespace chaos::service_common::persistence::data_access;
 chaos::service_common::persistence::data_access::PersistenceDriverSetting DriverPoolManager::persistentSetting;
 chaos::service_common::persistence::data_access::PersistenceDriverSetting DriverPoolManager::objectSetting;
 chaos::service_common::persistence::data_access::PersistenceDriverSetting DriverPoolManager::logSetting;
-chaos::common::cache_system::CacheDriverSetting DriverPoolManager::cacheSetting;
+chaos::common::cache_system::CacheDriverSetting                           DriverPoolManager::cacheSetting;
 //-------------------------------------------global pool---------------------------------------
 DriverPoolManager::DriverPoolManager() {}
 
 DriverPoolManager::~DriverPoolManager() {}
 
-void DriverPoolManager::init(void *init_data)  {
-    //init cache pool
-    //InizializableService::initImplementation(cache_pool, NULL, "CacheDriverPool", __PRETTY_FUNCTION__);
-    const std::string cache_impl_name = cacheSetting.cache_driver_impl+"CacheDriver";
-    if(cacheSetting.cache_driver_impl.size()){
-    #if CHAOS_PROMETHEUS
-        cache_driver.reset(new CacheDriverMetricCollector(ObjectFactoryRegister<chaos::common::cache_system::CacheDriver>::getInstance()->getNewInstanceByName(cache_impl_name)), cache_impl_name);
-    #else
-        cache_driver.reset(ObjectFactoryRegister<chaos::common::cache_system::CacheDriver>::getInstance()->getNewInstanceByName(cache_impl_name),
-                        cache_impl_name);
-    #endif
-        
-        if(cache_driver.get() == NULL) throw chaos::CException(-1, CHAOS_FORMAT("No %1% Cache Driver found", %cache_impl_name), __PRETTY_FUNCTION__);
-        cache_driver.init((void*)&cacheSetting, __PRETTY_FUNCTION__);
-    }
-    //init dirver instace
-    const std::string persistence_impl_name = persistentSetting.persistence_implementation+"PersistenceDriver";
-    if(persistentSetting.persistence_implementation.size()){
-        persistence_driver.reset(ObjectFactoryRegister<chaos::service_common::persistence::data_access::AbstractPersistenceDriver>::getInstance()->getNewInstanceByName(persistence_impl_name),
-                                persistence_impl_name);
-        if(persistence_driver.get() == NULL) throw chaos::CException(-1, CHAOS_FORMAT("No %1% Persistence Driver found", %persistence_impl_name), __PRETTY_FUNCTION__);
-        persistence_driver.init((void*)&persistentSetting, __PRETTY_FUNCTION__);
+void DriverPoolManager::init(void* init_data) {
+  //init cache pool
+  //InizializableService::initImplementation(cache_pool, NULL, "CacheDriverPool", __PRETTY_FUNCTION__);
+  const std::string cache_impl_name = cacheSetting.cache_driver_impl + "CacheDriver";
+  if (cacheSetting.cache_driver_impl.size()) {
+#if CHAOS_PROMETHEUS
+    cache_driver.reset(new CacheDriverMetricCollector(ObjectFactoryRegister<chaos::common::cache_system::CacheDriver>::getInstance()->getNewInstanceByName(cache_impl_name)), cache_impl_name);
+#else
+    cache_driver.reset(ObjectFactoryRegister<chaos::common::cache_system::CacheDriver>::getInstance()->getNewInstanceByName(cache_impl_name),
+                       cache_impl_name);
+#endif
+
+    if (cache_driver.get() == NULL) throw chaos::CException(-1, CHAOS_FORMAT("No %1% Cache Driver found", % cache_impl_name), __PRETTY_FUNCTION__);
+    try {
+      cache_driver.init((void*)&cacheSetting, __PRETTY_FUNCTION__);
+    } catch (CException& e) {
+      cache_driver.reset(NULL,cache_impl_name);
+      throw e;
+    } catch (...) {
+      DP_LOG_ERR << " Undefined exception catchd during initialization of cache driver";
+
+      cache_driver.reset(NULL,cache_impl_name);
     }
-    const std::string storage_impl_name = objectSetting.persistence_implementation + "ObjectStorageDriver";
-    if(objectSetting.persistence_implementation.size()){
-        storage_driver.reset(ObjectFactoryRegister<chaos::service_common::persistence::data_access::AbstractPersistenceDriver>::getInstance()->getNewInstanceByName(storage_impl_name),
-                            storage_impl_name);
-        if(storage_driver.get() == NULL) throw chaos::CException(-1, CHAOS_FORMAT("No %1% Object Storage Driver found", %storage_impl_name), __PRETTY_FUNCTION__);
-        storage_driver.init((void*)&objectSetting, __PRETTY_FUNCTION__);
+  }
+  //init dirver instace
+  const std::string persistence_impl_name = persistentSetting.persistence_implementation + "PersistenceDriver";
+  if (persistentSetting.persistence_implementation.size()) {
+    persistence_driver.reset(ObjectFactoryRegister<chaos::service_common::persistence::data_access::AbstractPersistenceDriver>::getInstance()->getNewInstanceByName(persistence_impl_name),
+                             persistence_impl_name);
+    if (persistence_driver.get() == NULL) throw chaos::CException(-1, CHAOS_FORMAT("No %1% Persistence Driver found", % persistence_impl_name), __PRETTY_FUNCTION__);
+    try {
+      persistence_driver.init((void*)&persistentSetting, __PRETTY_FUNCTION__);
+    } catch (CException& e) {
+      persistence_driver.reset(NULL,persistence_impl_name);
+      throw e;
+    } catch (...) {
+      DP_LOG_ERR << " Undefined exception catchd during initialization of persistent driver";
+
+      persistence_driver.reset(NULL,persistence_impl_name);
     }
-    const std::string log_impl_name = logSetting.persistence_implementation + "LogStorageDriver";
-    if(logSetting.persistence_implementation.size()){
-        log_driver.reset(ObjectFactoryRegister<chaos::service_common::persistence::data_access::AbstractPersistenceDriver>::getInstance()->getNewInstanceByName(log_impl_name),
-                         log_impl_name);
-        if(log_driver.get() == NULL) {
-            DP_LOG_INFO<< " Log driver not defined";
-        } else {
-            log_driver.init((void*)&logSetting, __PRETTY_FUNCTION__);
-        }
+  }
+  const std::string storage_impl_name = objectSetting.persistence_implementation + "ObjectStorageDriver";
+  if (objectSetting.persistence_implementation.size()) {
+    storage_driver.reset(ObjectFactoryRegister<chaos::service_common::persistence::data_access::AbstractPersistenceDriver>::getInstance()->getNewInstanceByName(storage_impl_name),
+                         storage_impl_name);
+    if (storage_driver.get() == NULL) throw chaos::CException(-1, CHAOS_FORMAT("No %1% Object Storage Driver found", % storage_impl_name), __PRETTY_FUNCTION__);
+    try {
+      storage_driver.init((void*)&objectSetting, __PRETTY_FUNCTION__);
+    } catch (CException& e) {
+      storage_driver.reset(NULL,storage_impl_name);
+      throw e;
+    } catch (...) {
+      DP_LOG_ERR << " Undefined exception catchd during initialization of storage driver";
+
+      storage_driver.reset(NULL,storage_impl_name);
     }
+  }
+  const std::string log_impl_name = logSetting.persistence_implementation + "LogStorageDriver";
+  if (logSetting.persistence_implementation.size()) {
+    log_driver.reset(ObjectFactoryRegister<chaos::service_common::persistence::data_access::AbstractPersistenceDriver>::getInstance()->getNewInstanceByName(log_impl_name),
+                     log_impl_name);
+    if (log_driver.get() == NULL) {
+      DP_LOG_INFO << " Log driver not defined";
+    } else {
+      try {
+        log_driver.init((void*)&logSetting, __PRETTY_FUNCTION__);
+      } catch (CException& e) {
+        log_driver.reset(NULL,log_impl_name);
+        throw e;
+      } catch (...) {
+        DP_LOG_ERR << " Undefined exception catchd during initialization of LOG driver";
 
-    
+        log_driver.reset(NULL,log_impl_name);
+      }
+    }
+  }
 }
 
-void DriverPoolManager::deinit()  {
-    storage_driver.deinit(__PRETTY_FUNCTION__);
-    persistence_driver.deinit(__PRETTY_FUNCTION__);
-    cache_driver.deinit(__PRETTY_FUNCTION__);
-    if(log_driver.get()){
-        log_driver.deinit(__PRETTY_FUNCTION__);
-    }
+void DriverPoolManager::deinit() {
+  storage_driver.deinit(__PRETTY_FUNCTION__);
+  persistence_driver.deinit(__PRETTY_FUNCTION__);
+  cache_driver.deinit(__PRETTY_FUNCTION__);
+  if (log_driver.get()) {
+    log_driver.deinit(__PRETTY_FUNCTION__);
+  }
 }
 
 //--------------cach driver pool method--------------
 chaos::common::cache_system::CacheDriver& DriverPoolManager::getCacheDrv() {
-    return *cache_driver;
+  return *cache_driver;
 }
 
 AbstractPersistenceDriver& DriverPoolManager::getPersistenceDrv() {
-    return *persistence_driver;
+  return *persistence_driver;
 }
 chaos::common::cache_system::CacheDriver* DriverPoolManager::getCacheDrvPtr() {
-    return cache_driver.get();
+  return cache_driver.get();
 }
 
 AbstractPersistenceDriver* DriverPoolManager::getPersistenceDrvPtr() {
-    return persistence_driver.get();
+  return persistence_driver.get();
 }
-chaos::service_common::persistence::data_access::AbstractPersistenceDriver* DriverPoolManager::getObjectStorageDrvPtr(){
-      return storage_driver.get();
+chaos::service_common::persistence::data_access::AbstractPersistenceDriver* DriverPoolManager::getObjectStorageDrvPtr() {
+  return storage_driver.get();
 }
 
 AbstractPersistenceDriver& DriverPoolManager::getObjectStorageDrv() {
-    return *storage_driver;
+  return *storage_driver;
 }
 AbstractPersistenceDriver& DriverPoolManager::getLogDrv() {
-    return *log_driver;
+  return *log_driver;
 }
 AbstractPersistenceDriver* DriverPoolManager::getLogDrvPtr() {
-    return log_driver.get();
+  return log_driver.get();
 }
\ No newline at end of file
diff --git a/config/CMakeChaos.txt b/config/CMakeChaos.txt
index ac8a7e2d3b17151a6135dba99c9bc6fcb02d6195..2dc561e4db55f944f608717c3f1345170443ffce 100644
--- a/config/CMakeChaos.txt
+++ b/config/CMakeChaos.txt
@@ -57,6 +57,7 @@ option(CHAOS_DRIVER_CCALT "Driver CCALT" ON)
 option(CHAOS_DRIVER_LUMINOMETER "Driver Luminometer" OFF)
 option(CHAOS_ENABLE_ZMQ_MONITOR "Enable ZMQ Monitor" OFF)
 option(CHAOS_EPICS_SUPPORT "Enable EPICS SUPPORT/DRIVERS" OFF)
+option(KAFKA_RDK_ENABLE "Enable KAFKA" ON)
 
 option(GPUFIT "Fast Fitting libraries (needs CUDA toolkit)" OFF)