From a1423371d0f604f77fe0a71621a77f79857ea9b2 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Mon, 2 Jul 2012 15:08:15 +0200 Subject: [PATCH] Moved configrpc code into the cibsync module. --- components/Makefile.am | 1 - components/cibsync/cibsynccomponent.cpp | 193 ++++++++++++++++ components/cibsync/cibsynccomponent.h | 18 ++ components/configrpc/Makefile.am | 27 --- components/configrpc/configrpc.vcxproj | 97 -------- components/configrpc/configrpccomponent.cpp | 235 -------------------- components/configrpc/configrpccomponent.h | 58 ----- components/configrpc/i2-configrpc.h | 35 --- configure.ac | 1 - 9 files changed, 211 insertions(+), 454 deletions(-) delete mode 100644 components/configrpc/Makefile.am delete mode 100644 components/configrpc/configrpc.vcxproj delete mode 100644 components/configrpc/configrpccomponent.cpp delete mode 100644 components/configrpc/configrpccomponent.h delete mode 100644 components/configrpc/i2-configrpc.h diff --git a/components/Makefile.am b/components/Makefile.am index d8211bb52..b54490e97 100644 --- a/components/Makefile.am +++ b/components/Makefile.am @@ -6,7 +6,6 @@ SUBDIRS = \ cibsync \ compat \ configfile \ - configrpc \ delegation \ demo \ discovery diff --git a/components/cibsync/cibsynccomponent.cpp b/components/cibsync/cibsynccomponent.cpp index a616fd360..501764d76 100644 --- a/components/cibsync/cibsynccomponent.cpp +++ b/components/cibsync/cibsynccomponent.cpp @@ -36,9 +36,33 @@ string CIBSyncComponent::GetName(void) const */ void CIBSyncComponent::Start(void) { + m_SyncingConfig = false; + m_Endpoint = boost::make_shared(); + + /* config objects */ + m_Endpoint->RegisterTopicHandler("config::FetchObjects", + boost::bind(&CIBSyncComponent::FetchObjectsHandler, this, _2)); + + ConfigObject::GetAllObjects()->OnObjectAdded.connect(boost::bind(&CIBSyncComponent::LocalObjectCommittedHandler, this, _2)); + ConfigObject::GetAllObjects()->OnObjectCommitted.connect(boost::bind(&CIBSyncComponent::LocalObjectCommittedHandler, this, _2)); + ConfigObject::GetAllObjects()->OnObjectRemoved.connect(boost::bind(&CIBSyncComponent::LocalObjectRemovedHandler, this, _2)); + + m_Endpoint->RegisterPublication("config::ObjectCommitted"); + m_Endpoint->RegisterPublication("config::ObjectRemoved"); + + EndpointManager::GetInstance()->OnNewEndpoint.connect(boost::bind(&CIBSyncComponent::NewEndpointHandler, this, _2)); + + m_Endpoint->RegisterPublication("config::FetchObjects"); + m_Endpoint->RegisterTopicHandler("config::ObjectCommitted", + boost::bind(&CIBSyncComponent::RemoteObjectCommittedHandler, this, _2, _3)); + m_Endpoint->RegisterTopicHandler("config::ObjectRemoved", + boost::bind(&CIBSyncComponent::RemoteObjectRemovedHandler, this, _3)); + + /* service status */ m_Endpoint->RegisterTopicHandler("delegation::ServiceStatus", boost::bind(&CIBSyncComponent::ServiceStatusRequestHandler, _2, _3)); + EndpointManager::GetInstance()->RegisterEndpoint(m_Endpoint); } @@ -102,4 +126,173 @@ void CIBSyncComponent::ServiceStatusRequestHandler(const Endpoint::Ptr& sender, CIB::UpdateTaskStatistics(now, 1); } +void CIBSyncComponent::NewEndpointHandler(const Endpoint::Ptr& endpoint) +{ + /* no need to sync the config with local endpoints */ + if (endpoint->IsLocal()) + return; + + endpoint->OnSessionEstablished.connect(boost::bind(&CIBSyncComponent::SessionEstablishedHandler, this, _1)); +} + +void CIBSyncComponent::SessionEstablishedHandler(const Endpoint::Ptr& endpoint) +{ + RequestMessage request; + request.SetMethod("config::FetchObjects"); + + EndpointManager::GetInstance()->SendUnicastMessage(m_Endpoint, endpoint, request); +} + +RequestMessage CIBSyncComponent::MakeObjectMessage(const ConfigObject::Ptr& object, string method, bool includeProperties) +{ + RequestMessage msg; + msg.SetMethod(method); + + MessagePart params; + msg.SetParams(params); + + params.SetProperty("name", object->GetName()); + params.SetProperty("type", object->GetType()); + + if (includeProperties) + params.SetProperty("properties", object->GetProperties()); + + return msg; +} + +bool CIBSyncComponent::ShouldReplicateObject(const ConfigObject::Ptr& object) +{ + return (!object->IsLocal()); +} + +void CIBSyncComponent::FetchObjectsHandler(const Endpoint::Ptr& sender) +{ + ConfigObject::Set::Ptr allObjects = ConfigObject::GetAllObjects(); + + for (ConfigObject::Set::Iterator ci = allObjects->Begin(); ci != allObjects->End(); ci++) { + ConfigObject::Ptr object = *ci; + + if (!ShouldReplicateObject(object)) + continue; + + RequestMessage request = MakeObjectMessage(object, "config::ObjectCommitted", true); + + EndpointManager::GetInstance()->SendUnicastMessage(m_Endpoint, sender, request); + } +} + +void CIBSyncComponent::LocalObjectCommittedHandler(const ConfigObject::Ptr& object) +{ + /* don't send messages when we're currently processing a remote update */ + if (m_SyncingConfig) + return; + + if (!ShouldReplicateObject(object)) + return; + + EndpointManager::GetInstance()->SendMulticastMessage(m_Endpoint, + MakeObjectMessage(object, "config::ObjectCommitted", true)); +} + +void CIBSyncComponent::LocalObjectRemovedHandler(const ConfigObject::Ptr& object) +{ + /* don't send messages when we're currently processing a remote update */ + if (m_SyncingConfig) + return; + + if (!ShouldReplicateObject(object)) + return; + + EndpointManager::GetInstance()->SendMulticastMessage(m_Endpoint, + MakeObjectMessage(object, "config::ObjectRemoved", false)); +} + +void CIBSyncComponent::RemoteObjectCommittedHandler(const Endpoint::Ptr& sender, const RequestMessage& request) +{ + MessagePart params; + if (!request.GetParams(¶ms)) + return; + + string name; + if (!params.GetProperty("name", &name)) + return; + + string type; + if (!params.GetProperty("type", &type)) + return; + + MessagePart properties; + if (!params.GetProperty("properties", &properties)) + return; + + ConfigObject::Ptr object = ConfigObject::GetObject(type, name); + + if (!object) { + object = boost::make_shared(properties.GetDictionary()); + + if (object->GetSource() == EndpointManager::GetInstance()->GetIdentity()) { + /* the peer sent us an object that was originally created by us - + * however if was deleted locally so we have to tell the peer to destroy + * its copy of the object. */ + EndpointManager::GetInstance()->SendMulticastMessage(m_Endpoint, + MakeObjectMessage(object, "config::ObjectRemoved", false)); + + return; + } + } else { + /* TODO: compare transaction timestamps and reject the update if our local object is newer */ + + object->SetProperties(properties.GetDictionary()); + } + + if (object->IsLocal()) + throw invalid_argument("Replicated remote object is marked as local."); + + if (object->GetSource().empty()) + object->SetSource(sender->GetIdentity()); + + try { + /* TODO: only ignore updates for _this_ object rather than all objects + * this might be relevant if the commit handler for this object + * creates other objects. */ + m_SyncingConfig = true; + object->Commit(); + m_SyncingConfig = false; + } catch (const std::exception& ex) { + m_SyncingConfig = false; + throw; + } +} + +void CIBSyncComponent::RemoteObjectRemovedHandler(const RequestMessage& request) +{ + MessagePart params; + if (!request.GetParams(¶ms)) + return; + + string name; + if (!params.GetProperty("name", &name)) + return; + + string type; + if (!params.GetProperty("type", &type)) + return; + + ConfigObject::Ptr object = ConfigObject::GetObject(type, name); + + if (!object) + return; + + if (!object->IsLocal()) { + try { + m_SyncingConfig = true; + object->Unregister(); + m_SyncingConfig = false; + } catch (const std::exception& ex) { + m_SyncingConfig = false; + throw; + } + } +} + EXPORT_COMPONENT(cibsync, CIBSyncComponent); diff --git a/components/cibsync/cibsynccomponent.h b/components/cibsync/cibsynccomponent.h index dc71fe6e2..95dae5828 100644 --- a/components/cibsync/cibsynccomponent.h +++ b/components/cibsync/cibsynccomponent.h @@ -37,6 +37,24 @@ private: VirtualEndpoint::Ptr m_Endpoint; static void ServiceStatusRequestHandler(const Endpoint::Ptr& sender, const RequestMessage& request); + + bool m_SyncingConfig; + + void NewEndpointHandler(const Endpoint::Ptr& endpoint); + void SessionEstablishedHandler(const Endpoint::Ptr& endpoint); + + void LocalObjectCommittedHandler(const ConfigObject::Ptr& object); + void LocalObjectRemovedHandler(const ConfigObject::Ptr& object); + + void FetchObjectsHandler(const Endpoint::Ptr& sender); + void RemoteObjectCommittedHandler(const Endpoint::Ptr& sender, const RequestMessage& request); + void RemoteObjectRemovedHandler(const RequestMessage& request); + + static RequestMessage MakeObjectMessage(const ConfigObject::Ptr& object, + string method, bool includeProperties); + + static bool ShouldReplicateObject(const ConfigObject::Ptr& object); + }; } diff --git a/components/configrpc/Makefile.am b/components/configrpc/Makefile.am deleted file mode 100644 index 054c8ebc2..000000000 --- a/components/configrpc/Makefile.am +++ /dev/null @@ -1,27 +0,0 @@ -## Process this file with automake to produce Makefile.in - -pkglib_LTLIBRARIES = \ - configrpc.la - -configrpc_la_SOURCES = \ - configrpccomponent.cpp \ - configrpccomponent.h \ - i2-configrpc.h - -configrpc_la_CPPFLAGS = \ - $(BOOST_CPPFLAGS) \ - -I${top_srcdir}/base \ - -I${top_srcdir}/jsonrpc \ - -I${top_srcdir}/icinga - -configrpc_la_LDFLAGS = \ - $(BOOST_LDFLAGS) \ - -module \ - -no-undefined \ - @RELEASE_INFO@ \ - @VERSION_INFO@ - -configrpc_la_LIBADD = \ - ${top_builddir}/base/libbase.la \ - ${top_builddir}/jsonrpc/libjsonrpc.la \ - ${top_builddir}/icinga/libicinga.la diff --git a/components/configrpc/configrpc.vcxproj b/components/configrpc/configrpc.vcxproj deleted file mode 100644 index eae5056e5..000000000 --- a/components/configrpc/configrpc.vcxproj +++ /dev/null @@ -1,97 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - - - - - - - - {697C6D7E-3109-484C-A7AF-384D28711610} - Win32Proj - icinga - - - - DynamicLibrary - true - MultiByte - - - DynamicLibrary - false - true - MultiByte - - - - - - - - - - - - - true - $(SolutionDir)\base;$(SolutionDir)\jsonrpc;$(SolutionDir)\icinga;$(SolutionDir)\dyn;$(IncludePath) - $(OutDir);$(LibraryPath) - - - false - $(SolutionDir)\base;$(SolutionDir)\jsonrpc;$(SolutionDir)\icinga;$(SolutionDir)\dyn;$(IncludePath) - $(OutDir);$(LibraryPath) - - - - - - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;CONFIGCOMPONENT_EXPORTS;%(PreprocessorDefinitions) - Level3 - true - false - - - Windows - true - base.lib;jsonrpc.lib;icinga.lib;cJSON.lib;%(AdditionalDependencies) - - - - - - - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;_USRDLL;CONFIGCOMPONENT_EXPORTS;%(PreprocessorDefinitions) - Speed - Level3 - true - false - - - Windows - true - true - true - base.lib;jsonrpc.lib;icinga.lib;cJSON.lib;%(AdditionalDependencies) - - - - - - \ No newline at end of file diff --git a/components/configrpc/configrpccomponent.cpp b/components/configrpc/configrpccomponent.cpp deleted file mode 100644 index 931281ced..000000000 --- a/components/configrpc/configrpccomponent.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/****************************************************************************** - * Icinga 2 * - * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License * - * as published by the Free Software Foundation; either version 2 * - * of the License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the Free Software Foundation * - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * - ******************************************************************************/ - -#include "i2-configrpc.h" - -using namespace icinga; - -string ConfigRpcComponent::GetName(void) const -{ - return "configcomponent"; -} - -void ConfigRpcComponent::Start(void) -{ - m_Syncing = false; - - EndpointManager::Ptr endpointManager = EndpointManager::GetInstance(); - - m_Endpoint = boost::make_shared(); - - m_Endpoint->RegisterTopicHandler("config::FetchObjects", - boost::bind(&ConfigRpcComponent::FetchObjectsHandler, this, _2)); - - ConfigObject::GetAllObjects()->OnObjectAdded.connect(boost::bind(&ConfigRpcComponent::LocalObjectCommittedHandler, this, _2)); - ConfigObject::GetAllObjects()->OnObjectCommitted.connect(boost::bind(&ConfigRpcComponent::LocalObjectCommittedHandler, this, _2)); - ConfigObject::GetAllObjects()->OnObjectRemoved.connect(boost::bind(&ConfigRpcComponent::LocalObjectRemovedHandler, this, _2)); - - m_Endpoint->RegisterPublication("config::ObjectCommitted"); - m_Endpoint->RegisterPublication("config::ObjectRemoved"); - - endpointManager->OnNewEndpoint.connect(boost::bind(&ConfigRpcComponent::NewEndpointHandler, this, _2)); - - m_Endpoint->RegisterPublication("config::FetchObjects"); - m_Endpoint->RegisterTopicHandler("config::ObjectCommitted", - boost::bind(&ConfigRpcComponent::RemoteObjectCommittedHandler, this, _2, _3)); - m_Endpoint->RegisterTopicHandler("config::ObjectRemoved", - boost::bind(&ConfigRpcComponent::RemoteObjectRemovedHandler, this, _3)); - - endpointManager->RegisterEndpoint(m_Endpoint); -} - -void ConfigRpcComponent::Stop(void) -{ - EndpointManager::Ptr mgr = EndpointManager::GetInstance(); - - if (mgr) - mgr->UnregisterEndpoint(m_Endpoint); -} - -void ConfigRpcComponent::NewEndpointHandler(const Endpoint::Ptr& endpoint) -{ - /* no need to sync the config with local endpoints */ - if (endpoint->IsLocal()) - return; - - endpoint->OnSessionEstablished.connect(boost::bind(&ConfigRpcComponent::SessionEstablishedHandler, this, _1)); -} - -void ConfigRpcComponent::SessionEstablishedHandler(const Endpoint::Ptr& endpoint) -{ - RequestMessage request; - request.SetMethod("config::FetchObjects"); - - EndpointManager::GetInstance()->SendUnicastMessage(m_Endpoint, endpoint, request); -} - -RequestMessage ConfigRpcComponent::MakeObjectMessage(const ConfigObject::Ptr& object, string method, bool includeProperties) -{ - RequestMessage msg; - msg.SetMethod(method); - - MessagePart params; - msg.SetParams(params); - - params.SetProperty("name", object->GetName()); - params.SetProperty("type", object->GetType()); - - if (includeProperties) - params.SetProperty("properties", object->GetProperties()); - - return msg; -} - -bool ConfigRpcComponent::ShouldReplicateObject(const ConfigObject::Ptr& object) -{ - return (!object->IsLocal()); -} - -void ConfigRpcComponent::FetchObjectsHandler(const Endpoint::Ptr& sender) -{ - ConfigObject::Set::Ptr allObjects = ConfigObject::GetAllObjects(); - - for (ConfigObject::Set::Iterator ci = allObjects->Begin(); ci != allObjects->End(); ci++) { - ConfigObject::Ptr object = *ci; - - if (!ShouldReplicateObject(object)) - continue; - - RequestMessage request = MakeObjectMessage(object, "config::ObjectCommitted", true); - - EndpointManager::GetInstance()->SendUnicastMessage(m_Endpoint, sender, request); - } -} - -void ConfigRpcComponent::LocalObjectCommittedHandler(const ConfigObject::Ptr& object) -{ - /* don't send messages when we're currently processing a remote update */ - if (m_Syncing) - return; - - if (!ShouldReplicateObject(object)) - return; - - EndpointManager::GetInstance()->SendMulticastMessage(m_Endpoint, - MakeObjectMessage(object, "config::ObjectCommitted", true)); -} - -void ConfigRpcComponent::LocalObjectRemovedHandler(const ConfigObject::Ptr& object) -{ - /* don't send messages when we're currently processing a remote update */ - if (m_Syncing) - return; - - if (!ShouldReplicateObject(object)) - return; - - EndpointManager::GetInstance()->SendMulticastMessage(m_Endpoint, - MakeObjectMessage(object, "config::ObjectRemoved", false)); -} - -void ConfigRpcComponent::RemoteObjectCommittedHandler(const Endpoint::Ptr& sender, const RequestMessage& request) -{ - MessagePart params; - if (!request.GetParams(¶ms)) - return; - - string name; - if (!params.GetProperty("name", &name)) - return; - - string type; - if (!params.GetProperty("type", &type)) - return; - - MessagePart properties; - if (!params.GetProperty("properties", &properties)) - return; - - ConfigObject::Ptr object = ConfigObject::GetObject(type, name); - - if (!object) { - object = boost::make_shared(properties.GetDictionary()); - - if (object->GetSource() == EndpointManager::GetInstance()->GetIdentity()) { - /* the peer sent us an object that was originally created by us - - * however if was deleted locally so we have to tell the peer to destroy - * its copy of the object. */ - EndpointManager::GetInstance()->SendMulticastMessage(m_Endpoint, - MakeObjectMessage(object, "config::ObjectRemoved", false)); - - return; - } - } else { - /* TODO: compare transaction timestamps and reject the update if our local object is newer */ - - object->SetProperties(properties.GetDictionary()); - } - - if (object->IsLocal()) - throw invalid_argument("Replicated remote object is marked as local."); - - if (object->GetSource().empty()) - object->SetSource(sender->GetIdentity()); - - try { - /* TODO: only ignore updates for _this_ object rather than all objects - * this might be relevant if the commit handler for this object - * creates other objects. */ - m_Syncing = true; - object->Commit(); - m_Syncing = false; - } catch (const std::exception& ex) { - m_Syncing = false; - throw; - } -} - -void ConfigRpcComponent::RemoteObjectRemovedHandler(const RequestMessage& request) -{ - MessagePart params; - if (!request.GetParams(¶ms)) - return; - - string name; - if (!params.GetProperty("name", &name)) - return; - - string type; - if (!params.GetProperty("type", &type)) - return; - - ConfigObject::Ptr object = ConfigObject::GetObject(type, name); - - if (!object) - return; - - if (!object->IsLocal()) { - try { - m_Syncing = true; - object->Unregister(); - m_Syncing = false; - } catch (const std::exception& ex) { - m_Syncing = false; - throw; - } - } -} - -EXPORT_COMPONENT(configrpc, ConfigRpcComponent); diff --git a/components/configrpc/configrpccomponent.h b/components/configrpc/configrpccomponent.h deleted file mode 100644 index 5e9bc073f..000000000 --- a/components/configrpc/configrpccomponent.h +++ /dev/null @@ -1,58 +0,0 @@ -/****************************************************************************** - * Icinga 2 * - * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License * - * as published by the Free Software Foundation; either version 2 * - * of the License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the Free Software Foundation * - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * - ******************************************************************************/ - -#ifndef CONFIGRPCCOMPONENT_H -#define CONFIGRPCCOMPONENT_H - -namespace icinga -{ - -/** - * @ingroup configrpc - */ -class ConfigRpcComponent : public Component -{ -public: - virtual string GetName(void) const; - virtual void Start(void); - virtual void Stop(void); - -private: - VirtualEndpoint::Ptr m_Endpoint; - bool m_Syncing; - - void NewEndpointHandler(const Endpoint::Ptr& endpoint); - void SessionEstablishedHandler(const Endpoint::Ptr& endpoint); - - void LocalObjectCommittedHandler(const ConfigObject::Ptr& object); - void LocalObjectRemovedHandler(const ConfigObject::Ptr& object); - - void FetchObjectsHandler(const Endpoint::Ptr& sender); - void RemoteObjectCommittedHandler(const Endpoint::Ptr& sender, const RequestMessage& request); - void RemoteObjectRemovedHandler(const RequestMessage& request); - - static RequestMessage MakeObjectMessage(const ConfigObject::Ptr& object, - string method, bool includeProperties); - - static bool ShouldReplicateObject(const ConfigObject::Ptr& object); -}; - -} - -#endif /* CONFIGRPCCOMPONENT_H */ diff --git a/components/configrpc/i2-configrpc.h b/components/configrpc/i2-configrpc.h deleted file mode 100644 index fee0b754b..000000000 --- a/components/configrpc/i2-configrpc.h +++ /dev/null @@ -1,35 +0,0 @@ -/****************************************************************************** - * Icinga 2 * - * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License * - * as published by the Free Software Foundation; either version 2 * - * of the License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the Free Software Foundation * - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * - ******************************************************************************/ - -#ifndef I2CONFIGRPC_H -#define I2CONFIGRPC_H - -/** - * @defgroup configrpc ConfigRpc component - * - * The ConfigRpc component replicates configuration objects to other peers. - */ - -#include -#include -#include - -#include "configrpccomponent.h" - -#endif /* I2CONFIGRPC_H */ diff --git a/configure.ac b/configure.ac index 27c47bb5a..1678990d7 100644 --- a/configure.ac +++ b/configure.ac @@ -72,7 +72,6 @@ components/checker/Makefile components/cibsync/Makefile components/compat/Makefile components/configfile/Makefile -components/configrpc/Makefile components/delegation/Makefile components/demo/Makefile components/discovery/Makefile