Refactor JSON-RPC library and implement check-result messages.

This commit is contained in:
Gunnar Beutner 2013-08-27 12:21:41 +02:00
parent 45b8d96461
commit f49bb3d150
59 changed files with 604 additions and 901 deletions

View File

@ -3,6 +3,7 @@
SUBDIRS = \
checker \
cluster \
compat \
demo \
ido_mysql \

View File

@ -33,5 +33,4 @@ libchecker_la_LIBADD = \
$(BOOST_SYSTEM_LIB) \
${top_builddir}/lib/base/libbase.la \
${top_builddir}/lib/config/libconfig.la \
${top_builddir}/lib/remoting/libremoting.la \
${top_builddir}/lib/icinga/libicinga.la

View File

@ -21,7 +21,6 @@
#define CHECKERCOMPONENT_H
#include "icinga/service.h"
#include "remoting/endpoint.h"
#include "base/dynamicobject.h"
#include "base/timer.h"
#include <boost/thread/thread.hpp>

1
components/cluster/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
cluster-type.cpp

View File

@ -1,36 +1,40 @@
## Process this file with automake to produce Makefile.in
pkglib_LTLIBRARIES = \
libremoting.la
libcluster.la
EXTRA_DIST = \
cluster-type.conf
.conf.cpp: $(top_builddir)/tools/mkembedconfig/mkembedconfig.c
$(top_builddir)/tools/mkembedconfig/mkembedconfig $< $@
libremoting_la_SOURCES = \
libcluster_la_SOURCES = \
clustercomponent.cpp \
clustercomponent.h \
cluster-type.cpp \
endpoint.cpp \
endpoint.h \
endpointmanager.cpp \
endpointmanager.h \
i2-remoting.h \
jsonrpc.cpp \
jsonrpc.h \
remoting-type.cpp
jsonrpc.h
libremoting_la_CPPFLAGS = \
-DI2_REMOTING_BUILD \
libcluster_la_CPPFLAGS = \
$(LTDLINCL) \
$(BOOST_CPPFLAGS) \
-I${top_srcdir}/lib
-I${top_srcdir}/lib \
-I${top_srcdir}/components
libremoting_la_LDFLAGS = \
libcluster_la_LDFLAGS = \
$(BOOST_LDFLAGS) \
-module \
-no-undefined \
@RELEASE_INFO@ \
@VERSION_INFO@
libremoting_la_LIBADD = \
libcluster_la_LIBADD = \
$(BOOST_SIGNALS_LIB) \
$(BOOST_THREAD_LIB) \
$(BOOST_SYSTEM_LIB) \
${top_builddir}/lib/base/libbase.la \
${top_builddir}/lib/config/libconfig.la
${top_builddir}/lib/config/libconfig.la \
${top_builddir}/lib/icinga/libicinga.la

View File

@ -17,8 +17,22 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
type Endpoint {
%attribute string "node",
%attribute string "service",
%attribute number "local"
type ClusterComponent {
%attribute string "cert_path",
%require "cert_path",
%attribute string "ca_path",
%require "ca_path",
%attribute string "bind_host",
%attribute string "bind_port",
%attribute array "peers" {
%attribute string "*"
}
}
type Endpoint {
%attribute string "host",
%attribute string "port"
}

View File

@ -18,54 +18,10 @@
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClInclude Include="endpoint.h" />
<ClInclude Include="endpointmanager.h" />
<ClInclude Include="i2-remoting.h" />
<ClInclude Include="jsonrpc.h" />
<ClInclude Include="requestmessage.h" />
<ClInclude Include="responsemessage.h" />
<ClInclude Include="messagepart.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="endpoint.cpp" />
<ClCompile Include="endpointmanager.cpp" />
<ClCompile Include="jsonrpc.cpp" />
<ClCompile Include="remoting-type.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="requestmessage.cpp" />
<ClCompile Include="responsemessage.cpp" />
<ClCompile Include="messagepart.cpp" />
</ItemGroup>
<ItemGroup>
<CustomBuild Include="remoting-type.conf">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(SolutionDir)$(Platform)\$(Configuration)\mkembedconfig.exe" "%(Identity)" "%(Filename).cpp"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Preparing config fragment for embedding</Message>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(SolutionDir)$(Platform)\$(Configuration)\mkembedconfig.exe" "%(Identity)" "%(Filename).cpp"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Preparing config fragment for embedding</Message>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(SolutionDir)$(Platform)\$(Configuration)\mkembedconfig.exe" "%(Identity)" "%(Filename).cpp"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Preparing config fragment for embedding</Message>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(SolutionDir)$(Platform)\$(Configuration)\mkembedconfig.exe" "%(Identity)" "%(Filename).cpp"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Preparing config fragment for embedding</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(Filename).cpp;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(Filename).cpp;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(Filename).cpp;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(Filename).cpp;%(Outputs)</Outputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\tools\mkembedconfig\mkembedconfig.c</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)\tools\mkembedconfig\mkembedconfig.c</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\tools\mkembedconfig\mkembedconfig.c</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)\tools\mkembedconfig\mkembedconfig.c</AdditionalInputs>
</CustomBuild>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{8DD52FAC-ECEE-48C2-B266-E7C47ED485F8}</ProjectGuid>
<ProjectGuid>{2E6C1133-730F-4875-A72C-B455B1DD4C5C}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>icinga</RootNamespace>
<RootNamespace>demo</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
@ -107,119 +63,130 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<IncludePath>$(SolutionDir)\lib;$(IncludePath)</IncludePath>
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(SolutionDir)\lib;$(SolutionDir)\components;$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)$(Platform)\$(Configuration)\;$(LibraryPath)</LibraryPath>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IncludePath>$(SolutionDir)\lib;$(IncludePath)</IncludePath>
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(SolutionDir)\lib;$(SolutionDir)\components;$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)$(Platform)\$(Configuration)\;$(LibraryPath)</LibraryPath>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<IncludePath>$(SolutionDir)\lib;$(IncludePath)</IncludePath>
<LinkIncremental>false</LinkIncremental>
<IncludePath>$(SolutionDir)\lib;$(SolutionDir)\components;$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)$(Platform)\$(Configuration)\;$(LibraryPath)</LibraryPath>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IncludePath>$(SolutionDir)\lib;$(IncludePath)</IncludePath>
<LinkIncremental>false</LinkIncremental>
<IncludePath>$(SolutionDir)\lib;$(SolutionDir)\components;$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)$(Platform)\$(Configuration)\;$(LibraryPath)</LibraryPath>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;I2_REMOTING_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_DEBUG;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>Level3</WarningLevel>
<MinimalRebuild>false</MinimalRebuild>
<PrecompiledHeaderFile>i2-remoting.h</PrecompiledHeaderFile>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>base.lib;config.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>base.lib;config.lib;remoting.lib;icinga.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<Lib>
<AdditionalDependencies>
</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;I2_REMOTING_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_DEBUG;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>Level3</WarningLevel>
<MinimalRebuild>false</MinimalRebuild>
<PrecompiledHeaderFile>i2-remoting.h</PrecompiledHeaderFile>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>base.lib;config.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>base.lib;config.lib;remoting.lib;icinga.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<Lib>
<AdditionalDependencies>
</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;I2_REMOTING_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<PreprocessorDefinitions>NDEBUG;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>Level3</WarningLevel>
<MinimalRebuild>false</MinimalRebuild>
<PrecompiledHeaderFile>i2-remoting.h</PrecompiledHeaderFile>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>base.lib;config.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>base.lib;config.lib;remoting.lib;icinga.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<Lib>
<AdditionalDependencies>
</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;I2_REMOTING_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<PreprocessorDefinitions>NDEBUG;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>Level3</WarningLevel>
<MinimalRebuild>false</MinimalRebuild>
<PrecompiledHeaderFile>i2-remoting.h</PrecompiledHeaderFile>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>base.lib;config.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>base.lib;config.lib;remoting.lib;icinga.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<Lib>
<AdditionalDependencies>
</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="democomponent.h" />
<ClInclude Include="i2-demo.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="demo-type.cpp" />
<ClCompile Include="democomponent.cpp" />
</ItemGroup>
<ItemGroup>
<CustomBuild Include="demo-type.conf">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(SolutionDir)$(Platform)\$(Configuration)\mkembedconfig.exe" "%(Identity)" "%(Filename).cpp"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Preparing config fragment for embedding</Message>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(SolutionDir)$(Platform)\$(Configuration)\mkembedconfig.exe" "%(Identity)" "%(Filename).cpp"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Preparing config fragment for embedding</Message>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(SolutionDir)$(Platform)\$(Configuration)\mkembedconfig.exe" "%(Identity)" "%(Filename).cpp"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Preparing config fragment for embedding</Message>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(SolutionDir)$(Platform)\$(Configuration)\mkembedconfig.exe" "%(Identity)" "%(Filename).cpp"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Preparing config fragment for embedding</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(Filename).cpp;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(Filename).cpp;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(Filename).cpp;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(Filename).cpp;%(Outputs)</Outputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\tools\mkembedconfig\mkembedconfig.c</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)\tools\mkembedconfig\mkembedconfig.c</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\tools\mkembedconfig\mkembedconfig.c</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)\tools\mkembedconfig\mkembedconfig.c</AdditionalInputs>
</CustomBuild>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClInclude Include="democomponent.h">
<Filter>Headerdateien</Filter>
</ClInclude>
<ClInclude Include="i2-demo.h">
<Filter>Headerdateien</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Headerdateien">
<UniqueIdentifier>{11a495bf-a705-4766-b3d3-9b5db266a6ef}</UniqueIdentifier>
</Filter>
<Filter Include="Quelldateien">
<UniqueIdentifier>{1fb6337f-a17f-46ea-9316-2d800a94b53d}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="democomponent.cpp">
<Filter>Quelldateien</Filter>
</ClCompile>
<ClCompile Include="demo-type.cpp">
<Filter>Quelldateien</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="demo-type.conf">
<Filter>Quelldateien</Filter>
</CustomBuild>
</ItemGroup>
</Project>

View File

@ -0,0 +1,316 @@
/******************************************************************************
* 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 "cluster/clustercomponent.h"
#include "cluster/endpoint.h"
#include "base/dynamictype.h"
#include "base/logger_fwd.h"
#include "base/objectlock.h"
#include "base/networkstream.h"
#include <boost/smart_ptr/make_shared.hpp>
using namespace icinga;
REGISTER_TYPE(ClusterComponent);
/**
* Starts the component.
*/
void ClusterComponent::Start(void)
{
DynamicObject::Start();
/* set up SSL context */
shared_ptr<X509> cert = GetX509Certificate(GetCertificateFile());
m_Identity = GetCertificateCN(cert);
Log(LogInformation, "cluster", "My identity: " + m_Identity);
m_SSLContext = MakeSSLContext(GetCertificateFile(), GetCertificateFile(), GetCAFile());
/* create the primary JSON-RPC listener */
if (!GetBindPort().IsEmpty())
AddListener(GetBindPort());
m_ReconnectTimer = boost::make_shared<Timer>();
m_ReconnectTimer->OnTimerExpired.connect(boost::bind(&ClusterComponent::ReconnectTimerHandler, this));
m_ReconnectTimer->SetInterval(5);
m_ReconnectTimer->Start();
Service::OnNewCheckResult.connect(bind(&ClusterComponent::CheckResultHandler, this, _1, _2));
Endpoint::OnMessageReceived.connect(bind(&ClusterComponent::MessageHandler, this, _1, _2));
}
/**
* Stops the component.
*/
void ClusterComponent::Stop(void)
{
/* Nothing to do here. */
}
String ClusterComponent::GetCertificateFile(void) const
{
ObjectLock olock(this);
return m_CertPath;
}
String ClusterComponent::GetCAFile(void) const
{
ObjectLock olock(this);
return m_CAPath;
}
String ClusterComponent::GetBindHost(void) const
{
ObjectLock olock(this);
return m_BindHost;
}
String ClusterComponent::GetBindPort(void) const
{
ObjectLock olock(this);
return m_BindPort;
}
Array::Ptr ClusterComponent::GetPeers(void) const
{
ObjectLock olock(this);
return m_Peers;
}
shared_ptr<SSL_CTX> ClusterComponent::GetSSLContext(void) const
{
ObjectLock olock(this);
return m_SSLContext;
}
String ClusterComponent::GetIdentity(void) const
{
ObjectLock olock(this);
return m_Identity;
}
/**
* Creates a new JSON-RPC listener on the specified port.
*
* @param service The port to listen on.
*/
void ClusterComponent::AddListener(const String& service)
{
ObjectLock olock(this);
shared_ptr<SSL_CTX> sslContext = m_SSLContext;
if (!sslContext)
BOOST_THROW_EXCEPTION(std::logic_error("SSL context is required for AddListener()"));
std::ostringstream s;
s << "Adding new listener: port " << service;
Log(LogInformation, "cluster", s.str());
TcpSocket::Ptr server = boost::make_shared<TcpSocket>();
server->Bind(service, AF_INET6);
boost::thread thread(boost::bind(&ClusterComponent::ListenerThreadProc, this, server));
thread.detach();
m_Servers.insert(server);
}
void ClusterComponent::ListenerThreadProc(const Socket::Ptr& server)
{
server->Listen();
for (;;) {
Socket::Ptr client = server->Accept();
try {
NewClientHandler(client, TlsRoleServer);
} catch (const std::exception& ex) {
std::stringstream message;
message << "Error for new JSON-RPC socket: " << boost::diagnostic_information(ex);
Log(LogInformation, "cluster", message.str());
}
}
}
/**
* Creates a new JSON-RPC client and connects to the specified host and port.
*
* @param node The remote host.
* @param service The remote port.
*/
void ClusterComponent::AddConnection(const String& node, const String& service) {
{
ObjectLock olock(this);
shared_ptr<SSL_CTX> sslContext = m_SSLContext;
if (!sslContext)
BOOST_THROW_EXCEPTION(std::logic_error("SSL context is required for AddConnection()"));
}
TcpSocket::Ptr client = boost::make_shared<TcpSocket>();
try {
client->Connect(node, service);
NewClientHandler(client, TlsRoleClient);
} catch (const std::exception& ex) {
Log(LogInformation, "cluster", "Could not connect to " + node + ":" + service + ": " + ex.what());
}
}
/**
* Processes a new client connection.
*
* @param client The new client.
*/
void ClusterComponent::NewClientHandler(const Socket::Ptr& client, TlsRole role)
{
NetworkStream::Ptr netStream = boost::make_shared<NetworkStream>(client);
TlsStream::Ptr tlsStream = boost::make_shared<TlsStream>(netStream, role, m_SSLContext);
tlsStream->Handshake();
shared_ptr<X509> cert = tlsStream->GetPeerCertificate();
String identity = GetCertificateCN(cert);
Log(LogInformation, "cluster", "New client connection for identity '" + identity + "'");
Endpoint::Ptr endpoint = Endpoint::GetByName(identity);
if (!endpoint) {
Log(LogInformation, "cluster", "Closing endpoint '" + identity + "': No configuration available.");
tlsStream->Close();
return;
}
endpoint->SetClient(tlsStream);
}
void ClusterComponent::ReconnectTimerHandler(void)
{
Array::Ptr peers = GetPeers();
if (!peers)
return;
ObjectLock olock(peers);
BOOST_FOREACH(const String& peer, peers) {
Endpoint::Ptr endpoint = Endpoint::GetByName(peer);
if (!endpoint)
continue;
if (endpoint->IsConnected())
continue;
String host, port;
host = endpoint->GetHost();
port = endpoint->GetPort();
if (host.IsEmpty() || port.IsEmpty()) {
Log(LogWarning, "cluster", "Can't reconnect "
"to endpoint '" + endpoint->GetName() + "': No "
"host/port information.");
continue;
}
Log(LogInformation, "cluster", "Attempting to reconnect to cluster endpoint '" + endpoint->GetName() + "' via '" + host + ":" + port + "'.");
AddConnection(host, port);
}
}
void ClusterComponent::CheckResultHandler(const Service::Ptr& service, const Dictionary::Ptr& cr)
{
if (cr->Contains("source") && cr->Get("source") != GetIdentity())
return;
cr->Set("source", GetIdentity());
Dictionary::Ptr params = boost::make_shared<Dictionary>();
params->Set("service", service->GetName());
params->Set("check_result", cr);
Dictionary::Ptr message = boost::make_shared<Dictionary>();
message->Set("jsonrpc", "2.0");
message->Set("method", "cluster::CheckResult");
message->Set("params", params);
BOOST_FOREACH(const Endpoint::Ptr& endpoint, DynamicType::GetObjects<Endpoint>()) {
endpoint->SendMessage(message);
}
}
void ClusterComponent::MessageHandler(const Endpoint::Ptr& endpoint, const Dictionary::Ptr& message)
{
if (message->Get("method") == "cluster::CheckResult") {
Dictionary::Ptr params = message->Get("params");
if (!params)
return;
Dictionary::Ptr cr = params->Get("check_result");
if (!cr)
return;
String svc = params->Get("service");
Service::Ptr service = Service::GetByName(svc);
if (!service)
return;
service->ProcessCheckResult(cr);
}
}
void ClusterComponent::InternalSerialize(const Dictionary::Ptr& bag, int attributeTypes) const
{
DynamicObject::InternalSerialize(bag, attributeTypes);
if (attributeTypes & Attribute_Config) {
bag->Set("cert_path", m_CertPath);
bag->Set("ca_path", m_CAPath);
bag->Set("bind_host", m_BindHost);
bag->Set("bind_port", m_BindPort);
bag->Set("peers", m_Peers);
}
}
void ClusterComponent::InternalDeserialize(const Dictionary::Ptr& bag, int attributeTypes)
{
DynamicObject::InternalDeserialize(bag, attributeTypes);
if (attributeTypes & Attribute_Config) {
m_CertPath = bag->Get("cert_path");
m_CAPath = bag->Get("ca_path");
m_BindHost = bag->Get("bind_host");
m_BindPort = bag->Get("bind_port");
m_Peers = bag->Get("peers");
}
}

View File

@ -17,68 +17,73 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#ifndef ENDPOINTMANAGER_H
#define ENDPOINTMANAGER_H
#ifndef CLUSTERCOMPONENT_H
#define CLUSTERCOMPONENT_H
#include "remoting/i2-remoting.h"
#include "remoting/endpoint.h"
#include "base/dynamicobject.h"
#include "base/timer.h"
#include "base/array.h"
#include "base/tcpsocket.h"
#include "base/tlsstream.h"
#include "base/timer.h"
#include "base/utility.h"
#include <boost/signals2.hpp>
#include "base/tlsutility.h"
#include "icinga/service.h"
#include "cluster/endpoint.h"
namespace icinga
{
/**
* Forwards messages between endpoints.
*
* @ingroup remoting
* @ingroup demo
*/
class I2_REMOTING_API EndpointManager : public Object
class ClusterComponent : public DynamicObject
{
public:
DECLARE_PTR_TYPEDEFS(EndpointManager);
DECLARE_PTR_TYPEDEFS(ClusterComponent);
DECLARE_TYPENAME(ClusterComponent);
EndpointManager(void);
virtual void Start(void);
virtual void Stop(void);
static EndpointManager *GetInstance(void);
String GetCertificateFile(void) const;
String GetCAFile(void) const;
String GetBindHost(void) const;
String GetBindPort(void) const;
Array::Ptr GetPeers(void) const;
void SetIdentity(const String& identity);
shared_ptr<SSL_CTX> GetSSLContext(void) const;
String GetIdentity(void) const;
void SetSSLContext(const shared_ptr<SSL_CTX>& sslContext);
shared_ptr<SSL_CTX> GetSSLContext(void) const;
protected:
virtual void InternalSerialize(const Dictionary::Ptr& bag, int attributeTypes) const;
virtual void InternalDeserialize(const Dictionary::Ptr& bag, int attributeTypes);
private:
String m_CertPath;
String m_CAPath;
String m_BindHost;
String m_BindPort;
Array::Ptr m_Peers;
shared_ptr<SSL_CTX> m_SSLContext;
String m_Identity;
Timer::Ptr m_ReconnectTimer;
void ReconnectTimerHandler(void);
std::set<TcpSocket::Ptr> m_Servers;
void AddListener(const String& service);
void AddConnection(const String& node, const String& service);
//void SendUnicastMessage(const Endpoint::Ptr& recipient, const Dictionary::Ptr& message);
//void SendUnicastMessage(const Endpoint::Ptr& sender, const Endpoint::Ptr& recipient, const MessagePart& message);
//void SendAnycastMessage(const Endpoint::Ptr& sender, const RequestMessage& message);
//void SendMulticastMessage(const RequestMessage& message);
//void SendMulticastMessage(const Endpoint::Ptr& sender, const RequestMessage& message);
boost::signals2::signal<void (const Endpoint::Ptr&)> OnNewEndpoint;
private:
String m_Identity;
Endpoint::Ptr m_Endpoint;
shared_ptr<SSL_CTX> m_SSLContext;
Timer::Ptr m_ReconnectTimer;
std::set<TcpSocket::Ptr> m_Servers;
void ReconnectTimerHandler(void);
void NewClientHandler(const Socket::Ptr& client, TlsRole role);
void ListenerThreadProc(const Socket::Ptr& server);
void CheckResultHandler(const Service::Ptr& service, const Dictionary::Ptr& cr);
void MessageHandler(const Endpoint::Ptr& endpoint, const Dictionary::Ptr& message);
};
}
#endif /* ENDPOINTMANAGER_H */
#endif /* CLUSTERCOMPONENT_H */

View File

@ -17,9 +17,8 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#include "remoting/endpoint.h"
#include "remoting/endpointmanager.h"
#include "remoting/jsonrpc.h"
#include "cluster/endpoint.h"
#include "cluster/jsonrpc.h"
#include "base/application.h"
#include "base/dynamictype.h"
#include "base/objectlock.h"
@ -78,7 +77,7 @@ void Endpoint::SendMessage(const Dictionary::Ptr& message)
} catch (const std::exception& ex) {
std::ostringstream msgbuf;
msgbuf << "Error while sending JSON-RPC message for endpoint '" << GetName() << "': " << boost::diagnostic_information(ex);
Log(LogWarning, "remoting", msgbuf.str());
Log(LogWarning, "cluster", msgbuf.str());
m_Client.reset();
}
@ -92,9 +91,11 @@ void Endpoint::MessageThreadProc(const Stream::Ptr& stream)
try {
message = JsonRpc::ReadMessage(stream);
} catch (const std::exception& ex) {
Log(LogWarning, "jsonrpc", "Error while reading JSON-RPC message for endpoint '" + GetName() + "': " + boost::diagnostic_information(ex));
Log(LogWarning, "cluster", "Error while reading JSON-RPC message for endpoint '" + GetName() + "': " + boost::diagnostic_information(ex));
m_Client.reset();
return;
}
Utility::QueueAsyncCallback(bind(boost::ref(Endpoint::OnMessageReceived), GetSelf(), message));

View File

@ -20,7 +20,6 @@
#ifndef ENDPOINT_H
#define ENDPOINT_H
#include "remoting/i2-remoting.h"
#include "base/dynamicobject.h"
#include "base/stream.h"
#include <boost/signals2.hpp>
@ -33,9 +32,9 @@ class EndpointManager;
/**
* An endpoint that can be used to send and receive messages.
*
* @ingroup remoting
* @ingroup cluster
*/
class I2_REMOTING_API Endpoint : public DynamicObject
class Endpoint : public DynamicObject
{
public:
DECLARE_PTR_TYPEDEFS(Endpoint);

View File

@ -17,7 +17,7 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#include "remoting/jsonrpc.h"
#include "cluster/jsonrpc.h"
#include "base/netstring.h"
#include "base/objectlock.h"
#include "base/logger_fwd.h"

View File

@ -20,7 +20,6 @@
#ifndef JSONRPC_H
#define JSONRPC_H
#include "remoting/i2-remoting.h"
#include "base/stream.h"
#include "base/dictionary.h"
@ -30,9 +29,9 @@ namespace icinga
/**
* A JSON-RPC connection.
*
* @ingroup remoting
* @ingroup cluster
*/
class I2_REMOTING_API JsonRpc
class JsonRpc
{
public:
static void SendMessage(const Stream::Ptr& stream, const Dictionary::Ptr& message);

View File

@ -37,5 +37,4 @@ libcompat_la_LIBADD = \
$(BOOST_SYSTEM_LIB) \
${top_builddir}/lib/base/libbase.la \
${top_builddir}/lib/config/libconfig.la \
${top_builddir}/lib/remoting/libremoting.la \
${top_builddir}/lib/icinga/libicinga.la

View File

@ -20,7 +20,6 @@
#ifndef CHECKRESULTREADER_H
#define CHECKRESULTREADER_H
#include "remoting/endpoint.h"
#include "base/dynamicobject.h"
#include "base/timer.h"
#include <fstream>

View File

@ -21,7 +21,6 @@
#define COMPATLOG_H
#include "icinga/service.h"
#include "remoting/endpoint.h"
#include "base/dynamicobject.h"
#include "base/timer.h"
#include <fstream>

View File

@ -33,5 +33,4 @@ libdemo_la_LIBADD = \
$(BOOST_SYSTEM_LIB) \
${top_builddir}/lib/base/libbase.la \
${top_builddir}/lib/config/libconfig.la \
${top_builddir}/lib/remoting/libremoting.la \
${top_builddir}/lib/icinga/libicinga.la

View File

@ -18,7 +18,6 @@
******************************************************************************/
#include "demo/democomponent.h"
#include "remoting/endpointmanager.h"
#include "base/dynamictype.h"
#include "base/logger_fwd.h"
#include <boost/smart_ptr/make_shared.hpp>

View File

@ -20,7 +20,6 @@
#ifndef DEMOCOMPONENT_H
#define DEMOCOMPONENT_H
#include "remoting/endpoint.h"
#include "base/dynamicobject.h"
#include "base/timer.h"
@ -34,6 +33,7 @@ class DemoComponent : public DynamicObject
{
public:
DECLARE_PTR_TYPEDEFS(DemoComponent);
DECLARE_TYPENAME(DemoComponent);
virtual void Start(void);
virtual void Stop(void);

View File

@ -36,7 +36,6 @@ libido_mysql_la_LIBADD = \
$(BOOST_SYSTEM_LIB) \
${top_builddir}/lib/base/libbase.la \
${top_builddir}/lib/config/libconfig.la \
${top_builddir}/lib/remoting/libremoting.la \
${top_builddir}/lib/icinga/libicinga.la \
${top_builddir}/lib/ido/libido.la

View File

@ -93,5 +93,4 @@ liblivestatus_la_LIBADD = \
$(BOOST_SYSTEM_LIB) \
${top_builddir}/lib/base/libbase.la \
${top_builddir}/lib/config/libconfig.la \
${top_builddir}/lib/remoting/libremoting.la \
${top_builddir}/lib/icinga/libicinga.la

View File

@ -33,5 +33,4 @@ libnotification_la_LIBADD = \
$(BOOST_SYSTEM_LIB) \
${top_builddir}/lib/base/libbase.la \
${top_builddir}/lib/config/libconfig.la \
${top_builddir}/lib/remoting/libremoting.la \
${top_builddir}/lib/icinga/libicinga.la

View File

@ -123,6 +123,7 @@ AC_CONFIG_FILES([
Makefile
components/Makefile
components/checker/Makefile
components/cluster/Makefile
components/compat/Makefile
components/demo/Makefile
components/ido_mysql/Makefile
@ -141,7 +142,6 @@ lib/config/Makefile
lib/icinga/Makefile
lib/ido/Makefile
lib/python/Makefile
lib/remoting/Makefile
test/Makefile
third-party/Makefile
third-party/cJSON/Makefile

View File

@ -1,8 +1,8 @@
-----BEGIN CERTIFICATE-----
MIICtzCCAiCgAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJERTEQ
MA4GA1UECAwHQmF2YXJpYTESMBAGA1UEBwwJTnVyZW1iZXJnMRUwEwYDVQQKDAxO
RVRXQVlTIEdtYkgxHDAaBgNVBAMME0ljaW5nYSBTbmFrZSBPaWwgQ0EwHhcNMTIw
NDI0MTE0NzQ2WhcNMTMwNDI0MTE0NzQ2WjBeMQswCQYDVQQGEwJERTEQMA4GA1UE
RVRXQVlTIEdtYkgxHDAaBgNVBAMME0ljaW5nYSBTbmFrZSBPaWwgQ0EwHhcNMTMw
ODI3MDcyNTE0WhcNMjMwODI1MDcyNTE0WjBeMQswCQYDVQQGEwJERTEQMA4GA1UE
CAwHQmF2YXJpYTESMBAGA1UEBwwJTnVyZW1iZXJnMRUwEwYDVQQKDAxORVRXQVlT
IEdtYkgxEjAQBgNVBAMMCWljaW5nYS1jMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
gYkCgYEAysHrzHs9WfQR4cEUx2hFZQmbM+Ssi5L63yqnzxEvVQ3GlM+uIceK1Kvx
@ -10,10 +10,10 @@ gYkCgYEAysHrzHs9WfQR4cEUx2hFZQmbM+Ssi5L63yqnzxEvVQ3GlM+uIceK1Kvx
CP3s5yC7ZZ6bDiPMhRi/TRvY6+uQf+yew5daA3p87jocgRjhRicCAwEAAaN7MHkw
CQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2Vy
dGlmaWNhdGUwHQYDVR0OBBYEFPzsYbQZdbq+pcFJWoenWREW6WhMMB8GA1UdIwQY
MBaAFNVJHVPJNwqEcG51lpqZJWVPaysFMA0GCSqGSIb3DQEBBQUAA4GBAMLP1GJf
0hFdrEpGq+NvxTVx7wD30enAot5x2HLx4HuFohQJz/VZ45v+srrA+HEXbBFXPOd4
nB2XtcDDidFKTt5E03HBwDGGZvnB3f1KXYi7B50imKrwVVzgp5nGBM4hSzWGovEX
EYofmhk0fQg9qiKQrjwNib/4/b0srwEswfdj
MBaAFNVJHVPJNwqEcG51lpqZJWVPaysFMA0GCSqGSIb3DQEBBQUAA4GBAKYB6Cds
jJh20DMXKXklftqNPiGcPjnwpka5u/ys//rkgzjYnLiE9jkP5d32JtQbEqUY9gqN
Ngu2HeHE4hGrbgvCj0aPepzJY3RvxIJwvX7nuKHjSitKwOsQYsOkTjTfOyhI8kSN
nOGsDr4xpMX/iJL3Q1O9MwVRseKF8s9U+zjV
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMrB68x7PVn0EeHB
@ -30,4 +30,4 @@ WLEQa8UZ5enQeOcKCTudgn7fWIUxAkEAmXWfXP6YZXVzvR+xt08225aEvTItEbKM
krFJNlLe4aNb1Hp6lO5ALnk6vDq8wSKZqGIFHBtq6vHNZFiix+xO8QJAIZ3pB/Bz
Il8NjZMg8t/1sJdn32Xe9D0lZRtZTKC8zF/78NDFEo9qqE4Sr1CUfqlx18HXOxCO
Vg4lv6+jUj+LmA==
-----END PRIVATE KEY-----
-----END PRIVATE KEY-----

View File

@ -1,8 +1,8 @@
-----BEGIN CERTIFICATE-----
MIICtzCCAiCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJERTEQ
MA4GA1UECAwHQmF2YXJpYTESMBAGA1UEBwwJTnVyZW1iZXJnMRUwEwYDVQQKDAxO
RVRXQVlTIEdtYkgxHDAaBgNVBAMME0ljaW5nYSBTbmFrZSBPaWwgQ0EwHhcNMTIw
NDI0MTE0NzU1WhcNMTMwNDI0MTE0NzU1WjBeMQswCQYDVQQGEwJERTEQMA4GA1UE
RVRXQVlTIEdtYkgxHDAaBgNVBAMME0ljaW5nYSBTbmFrZSBPaWwgQ0EwHhcNMTMw
ODI3MDcyNTQwWhcNMjMwODI1MDcyNTQwWjBeMQswCQYDVQQGEwJERTEQMA4GA1UE
CAwHQmF2YXJpYTESMBAGA1UEBwwJTnVyZW1iZXJnMRUwEwYDVQQKDAxORVRXQVlT
IEdtYkgxEjAQBgNVBAMMCWljaW5nYS1jMjCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
gYkCgYEArOcVui1AWojbPuK/7We9uwIBLaOLfBxQRI3+k6PzzjdtaXT4ijT/DSav
@ -10,10 +10,10 @@ Q5U4wGOLYh0yuSyqS88QX/DsqDGLXnSVs8mT37bioMOw2XinqaNQ6xK4vyi0FYxS
ewI6YOkYi7135NEaSUgd82hk4wFtiIb67T7hkHRc7Aui6FmT/SkCAwEAAaN7MHkw
CQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2Vy
dGlmaWNhdGUwHQYDVR0OBBYEFGvpolD5na6L70kNFO1tYGYIwDhqMB8GA1UdIwQY
MBaAFNVJHVPJNwqEcG51lpqZJWVPaysFMA0GCSqGSIb3DQEBBQUAA4GBAIhhjKWw
5JKirNidgG9PuD8x47VsRTkESLlq/pS7KjkE1nWCG9JpR5oVSzx2WXomiaAZ4q2C
WS1z4HD9HF4NbhY+xVBi0Fj/kotuXCCweRo5EVp7Q4fabm1maJemFwMTHGhBLu7a
v4dquYyOk9Dhkwcjajyn+KWceCoUTdI3LB2t
MBaAFNVJHVPJNwqEcG51lpqZJWVPaysFMA0GCSqGSIb3DQEBBQUAA4GBAFLLI1Il
q6SRYcsFGHw+mAA2Uw1ySAlpDQUS6GFcWjMKTaIMgzBDBVJixo8TsuajURXUlDsh
mKqpHdOsl5zU/KZHufn5sI1QrDTrUPMt8PqCqwmEoykgbbbxl/913HJ5XKDyzL/p
Pq8b9sMlI601pOQGFI939WueGgfOc4WRdlMS
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKznFbotQFqI2z7i

View File

@ -1,16 +1,19 @@
-----BEGIN CERTIFICATE-----
MIICNTCCAZ4CAQQwDQYJKoZIhvcNAQEFBQAwaDELMAkGA1UEBhMCREUxEDAOBgNV
BAgMB0JhdmFyaWExEjAQBgNVBAcMCU51cmVtYmVyZzEVMBMGA1UECgwMTkVUV0FZ
UyBHbWJIMRwwGgYDVQQDDBNJY2luZ2EgU25ha2UgT2lsIENBMB4XDTEyMDUwODA3
MzkxOVoXDTIyMDUwNjA3MzkxOVowXjELMAkGA1UEBhMCREUxEDAOBgNVBAgMB0Jh
dmFyaWExEjAQBgNVBAcMCU51cmVtYmVyZzEVMBMGA1UECgwMTkVUV0FZUyBHbWJI
MRIwEAYDVQQDDAlpY2luZ2EtYzMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB
AKFf+UkCgbNtEP0OoeF+K02L5SRlqkkkp6eaieh0IN7NNAxeELcGpZmycv4sHp30
qv0zDtKU1HYrpm8TEBsz2AoT+J36QT9IysfcWdM9o3WZGMDUVqYBUscurkxBQJCK
cFwXijTJ8Djn82xVgNUm/E44AdbrIwUlx23yllErx8hfAgMBAAEwDQYJKoZIhvcN
AQEFBQADgYEAsZOKZQ2+ksPiNTCJrY+uiUZs6lFSbcJ9BHHaAt0ytQPiblufz3xl
AR5Hza5fHt+lN9aGxM7TWMhjZHhmoctSRz8AW1KZTdbxJhRdbqmBjl95c2wBiDxs
ERpyU9m9Rp42IjTyU4Vr/yO7DgMcG2k4KYzNquA5O8rqqtPRAp3H6n0=
MIICtzCCAiCgAwIBAgIBAjANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJERTEQ
MA4GA1UECAwHQmF2YXJpYTESMBAGA1UEBwwJTnVyZW1iZXJnMRUwEwYDVQQKDAxO
RVRXQVlTIEdtYkgxHDAaBgNVBAMME0ljaW5nYSBTbmFrZSBPaWwgQ0EwHhcNMTMw
ODI3MDcyNTQ1WhcNMjMwODI1MDcyNTQ1WjBeMQswCQYDVQQGEwJERTEQMA4GA1UE
CAwHQmF2YXJpYTESMBAGA1UEBwwJTnVyZW1iZXJnMRUwEwYDVQQKDAxORVRXQVlT
IEdtYkgxEjAQBgNVBAMMCWljaW5nYS1jMzCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
gYkCgYEAoV/5SQKBs20Q/Q6h4X4rTYvlJGWqSSSnp5qJ6HQg3s00DF4QtwalmbJy
/iwenfSq/TMO0pTUdiumbxMQGzPYChP4nfpBP0jKx9xZ0z2jdZkYwNRWpgFSxy6u
TEFAkIpwXBeKNMnwOOfzbFWA1Sb8TjgB1usjBSXHbfKWUSvHyF8CAwEAAaN7MHkw
CQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2Vy
dGlmaWNhdGUwHQYDVR0OBBYEFEwxDpbbnj9CAJRPErpolPAjAi1bMB8GA1UdIwQY
MBaAFNVJHVPJNwqEcG51lpqZJWVPaysFMA0GCSqGSIb3DQEBBQUAA4GBAJMvQyvv
aXxu87au/X6+k6ghUImwGW/xqtrouyVZ3yX4zq9R/sZ1yA5jRq7e+IDjb04qraY7
ZwMCWqjUYFUzV4ViEx6m7bnm/Qv+pubmM7v8B4Obm1HJniVcJUMOzoGgKGQxjOCt
97EsiVQZGnss4PYjjxlW7T/QvqkZb4tbyyeE
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQChX/lJAoGzbRD9DqHhfitNi+UkZapJJKenmonodCDezTQMXhC3

View File

@ -26,13 +26,6 @@ class IcingaValuePrinter:
else:
return '<INVALID>'
class IcingaAttributePrinter:
def __init__(self, val):
self.val = val
def to_string(self):
return self.val['m_Value']
class IcingaSignalPrinter:
def __init__(self, val):
self.val = val
@ -40,16 +33,28 @@ class IcingaSignalPrinter:
def to_string(self):
return '<SIGNAL>'
class IcingaMutexPrinter:
def __init__(self, val):
self.val = val
def to_string(self):
owner = self.val['__data']['__owner']
if owner == 0:
return '<unlocked>'
else:
return '<locked by #' + owner + '>'
def lookup_icinga_type(val):
t = val.type.unqualified()
if str(t) == 'icinga::String':
return IcingaStringPrinter(val)
elif str(t) == 'icinga::Value':
return IcingaValuePrinter(val)
elif str(t) == 'icinga::AttributeBase' or re.match('^icinga::Attribute<.*>$', str(t)):
return IcingaAttributePrinter(val)
elif re.match('^boost::signals2::signal.*<.*>$', str(t)):
return IcingaSignalPrinter(val)
elif str(t) == 'pthread_mutex_t':
return IcingaMutexPrinter(val)
return None

View File

@ -4,7 +4,6 @@
SUBDIRS = \
base \
config \
remoting \
icinga \
ido \
python

View File

@ -26,13 +26,6 @@
using namespace icinga;
/**
* Constructor for the Array class.
*/
Array::Array(void)
: m_Sealed(false)
{ }
/**
* Restrieves a value from an array.
*
@ -58,9 +51,6 @@ void Array::Set(unsigned int index, const Value& value)
ASSERT(!OwnsLock());
ObjectLock olock(this);
if (m_Sealed)
BOOST_THROW_EXCEPTION(std::invalid_argument("Array must not be sealed."));
m_Data.at(index) = value;
}
@ -74,9 +64,6 @@ void Array::Add(const Value& value)
ASSERT(!OwnsLock());
ObjectLock olock(this);
if (m_Sealed)
BOOST_THROW_EXCEPTION(std::invalid_argument("Array must not be sealed."));
m_Data.push_back(value);
}
@ -131,9 +118,6 @@ void Array::Remove(unsigned int index)
ASSERT(!OwnsLock());
ObjectLock olock(this);
if (m_Sealed)
BOOST_THROW_EXCEPTION(std::invalid_argument("Array must not be sealed."));
m_Data.erase(m_Data.begin() + index);
}
@ -146,37 +130,9 @@ void Array::Remove(Array::Iterator it)
{
ASSERT(OwnsLock());
if (m_Sealed)
BOOST_THROW_EXCEPTION(std::invalid_argument("Array must not be sealed."));
m_Data.erase(it);
}
/**
* Marks the array as read-only. Attempting to modify a sealed
* array is an error.
*/
void Array::Seal(void)
{
ASSERT(!OwnsLock());
ObjectLock olock(this);
m_Sealed = true;
}
/**
* Checks whether the array is sealed.
*
* @returns true if the array is sealed, false otherwise.
*/
bool Array::IsSealed(void) const
{
ASSERT(!OwnsLock());
ObjectLock olock(this);
return m_Sealed;
}
/**
* Makes a shallow copy of an array.
*

View File

@ -42,15 +42,10 @@ public:
*/
typedef std::vector<Value>::iterator Iterator;
Array(void);
Value Get(unsigned int index) const;
void Set(unsigned int index, const Value& value);
void Add(const Value& value);
void Seal(void);
bool IsSealed(void) const;
Iterator Begin(void);
Iterator End(void);
@ -66,7 +61,6 @@ public:
private:
std::vector<Value> m_Data; /**< The data for the array. */
bool m_Sealed; /**< Whether the array is read-only. */
};
inline Array::Iterator range_begin(Array::Ptr x)

View File

@ -27,7 +27,7 @@
using namespace icinga;
BufferedStream::BufferedStream(const Stream::Ptr& innerStream)
: m_InnerStream(innerStream), m_Stopped(false),
: m_InnerStream(innerStream), m_Stopped(false), m_Eof(false),
m_RecvQ(boost::make_shared<FIFO>()), m_SendQ(boost::make_shared<FIFO>()),
m_Blocking(true), m_Exception()
{
@ -64,8 +64,15 @@ void BufferedStream::ReadThreadProc(void)
for (;;) {
size_t rc = m_InnerStream->Read(buffer, sizeof(buffer));
if (rc == 0)
if (rc == 0) {
boost::mutex::scoped_lock lock(m_Mutex);
m_Eof = true;
m_Stopped = true;
m_ReadCV.notify_all();
m_WriteCV.notify_all();
break;
}
boost::mutex::scoped_lock lock(m_Mutex);
m_RecvQ->Write(buffer, rc);
@ -173,7 +180,7 @@ void BufferedStream::WaitReadable(size_t count)
void BufferedStream::InternalWaitReadable(size_t count, boost::mutex::scoped_lock& lock)
{
while (m_RecvQ->GetAvailableBytes() < count && !m_Exception)
while (m_RecvQ->GetAvailableBytes() < count && !m_Exception && !m_Stopped)
m_ReadCV.wait(lock);
}
@ -186,3 +193,10 @@ void BufferedStream::MakeNonBlocking(void)
m_Blocking = false;
}
bool BufferedStream::IsEof(void) const
{
boost::mutex::scoped_lock lock(m_Mutex);
return m_Eof;
}

View File

@ -45,6 +45,8 @@ public:
virtual void Close(void);
virtual bool IsEof(void) const;
void WaitReadable(size_t count);
void WaitWritable(size_t count);
@ -54,6 +56,7 @@ private:
Stream::Ptr m_InnerStream;
bool m_Stopped;
bool m_Eof;
FIFO::Ptr m_RecvQ;
FIFO::Ptr m_SendQ;
@ -62,7 +65,7 @@ private:
boost::exception_ptr m_Exception;
boost::mutex m_Mutex;
mutable boost::mutex m_Mutex;
boost::condition_variable m_ReadCV;
boost::condition_variable m_WriteCV;

View File

@ -59,13 +59,6 @@ struct DictionaryKeyLessComparer
}
};
/**
* Constructor for the Dictionary class.
*/
Dictionary::Dictionary(void)
: m_Sealed(false)
{ }
/**
* Restrieves a value from a dictionary.
*
@ -114,9 +107,6 @@ void Dictionary::Set(const String& key, const Value& value)
ASSERT(!OwnsLock());
ObjectLock olock(this);
if (m_Sealed)
BOOST_THROW_EXCEPTION(std::invalid_argument("Dictionary must not be sealed."));
std::pair<std::map<String, Value>::iterator, bool> ret;
ret = m_Data.insert(std::make_pair(key, value));
if (!ret.second)
@ -194,9 +184,6 @@ void Dictionary::Remove(const String& key)
if (it == m_Data.end())
return;
if (m_Sealed)
BOOST_THROW_EXCEPTION(std::invalid_argument("Dictionary must not be sealed."));
m_Data.erase(it);
}
@ -209,37 +196,9 @@ void Dictionary::Remove(Dictionary::Iterator it)
{
ASSERT(OwnsLock());
if (m_Sealed)
BOOST_THROW_EXCEPTION(std::invalid_argument("Dictionary must not be sealed."));
m_Data.erase(it);
}
/**
* Marks the dictionary as read-only. Attempting to modify a sealed
* dictionary is an error.
*/
void Dictionary::Seal(void)
{
ASSERT(!OwnsLock());
ObjectLock olock(this);
m_Sealed = true;
}
/**
* Checks whether the dictionary is sealed.
*
* @returns true if the dictionary is sealed, false otherwise.
*/
bool Dictionary::IsSealed(void) const
{
ASSERT(!OwnsLock());
ObjectLock olock(this);
return m_Sealed;
}
/**
* Makes a shallow copy of a dictionary.
*

View File

@ -43,16 +43,11 @@ public:
*/
typedef std::map<String, Value>::iterator Iterator;
Dictionary(void);
Value Get(const char *key) const;
Value Get(const String& key) const;
void Set(const String& key, const Value& value);
bool Contains(const String& key) const;
void Seal(void);
bool IsSealed(void) const;
Iterator Begin(void);
Iterator End(void);
@ -68,7 +63,6 @@ public:
private:
std::map<String, Value> m_Data; /**< The data for the dictionary. */
bool m_Sealed; /**< Whether the dictionary is read-only. */
};
inline Dictionary::Iterator range_begin(Dictionary::Ptr x)

View File

@ -272,7 +272,7 @@ void DynamicObject::RestoreObjects(const String& filename, int attributeTypes)
DynamicType::Ptr dt = DynamicType::GetByName(type);
if (!dt)
BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid type: " + type));
continue;
DynamicObject::Ptr object = dt->GetObject(name);

View File

@ -111,6 +111,11 @@ void FIFO::Write(const void *buffer, size_t count)
void FIFO::Close(void)
{ }
bool FIFO::IsEof(void) const
{
return false;
}
size_t FIFO::GetAvailableBytes(void) const
{
return m_DataSize;

View File

@ -44,6 +44,7 @@ public:
virtual size_t Read(void *buffer, size_t count);
virtual void Write(const void *buffer, size_t count);
virtual void Close(void);
virtual bool IsEof(void) const;
size_t GetAvailableBytes(void) const;

View File

@ -25,7 +25,7 @@
using namespace icinga;
NetworkStream::NetworkStream(const Socket::Ptr& socket)
: m_Socket(socket)
: m_Socket(socket), m_Eof(false)
{ }
void NetworkStream::Close(void)
@ -43,7 +43,12 @@ void NetworkStream::Close(void)
*/
size_t NetworkStream::Read(void *buffer, size_t count)
{
return m_Socket->Read(buffer, count);
size_t rc = m_Socket->Read(buffer, count);
if (rc == 0)
m_Eof = true;
return rc;
}
/**
@ -59,3 +64,8 @@ void NetworkStream::Write(const void *buffer, size_t count)
if (rc < count)
BOOST_THROW_EXCEPTION(std::runtime_error("Short write for socket."));
}
bool NetworkStream::IsEof(void) const
{
return m_Eof;
}

View File

@ -44,8 +44,11 @@ public:
virtual void Close(void);
virtual bool IsEof(void) const;
private:
Socket::Ptr m_Socket;
bool m_Eof;
};
}

View File

@ -61,3 +61,8 @@ void StdioStream::Close(void)
m_OwnsStream = false;
}
}
bool StdioStream::IsEof(void) const
{
return m_InnerStream->eof();
}

View File

@ -39,6 +39,8 @@ public:
virtual void Close(void);
virtual bool IsEof(void) const;
private:
std::iostream *m_InnerStream;
bool m_OwnsStream;

View File

@ -74,6 +74,13 @@ public:
*/
virtual void Close(void) = 0;
/**
* Checks whether we've reached the end-of-file condition.
*
* @returns true if EOF.
*/
virtual bool IsEof(void) const = 0;
bool ReadLine(String *line, ReadLineContext& context);
};

View File

@ -111,7 +111,7 @@ static int I2Stream_read(BIO *bi, char *out, int outl)
return -1;
}
if (data_read == 0) {
if (data_read == 0 && !bp->StreamObj->IsEof()) {
BIO_set_retry_read(bi);
return -1;
}

View File

@ -214,3 +214,8 @@ void TlsStream::Close(void)
{
m_InnerStream->Close();
}
bool TlsStream::IsEof(void) const
{
return m_InnerStream->IsEof();
}

View File

@ -57,6 +57,8 @@ public:
virtual size_t Read(void *buffer, size_t count);
virtual void Write(const void *buffer, size_t count);
virtual bool IsEof(void) const;
private:
shared_ptr<SSL_CTX> m_SSLContext;
shared_ptr<SSL> m_SSL;

View File

@ -179,8 +179,6 @@ DynamicObject::Ptr ConfigItem::Commit(void)
}
}
attrs->Seal();
DynamicObject::Ptr dobj = dtype->CreateObject(attrs);
dobj->Register();

View File

@ -88,5 +88,4 @@ libicinga_la_LIBADD = \
$(BOOST_THREAD_LIB) \
$(BOOST_SYSTEM_LIB) \
${top_builddir}/lib/base/libbase.la \
${top_builddir}/lib/config/libconfig.la \
${top_builddir}/lib/remoting/libremoting.la
${top_builddir}/lib/config/libconfig.la

View File

@ -183,10 +183,6 @@ type HostGroup {
}
type IcingaApplication {
%attribute string "cert_path",
%attribute string "ca_path",
%attribute string "node",
%attribute string "service",
%attribute string "pid_path",
%attribute string "state_path",
%attribute dictionary "macros" {

View File

@ -18,7 +18,6 @@
******************************************************************************/
#include "icinga/icingaapplication.h"
#include "remoting/endpointmanager.h"
#include "base/dynamictype.h"
#include "base/logger_fwd.h"
#include "base/objectlock.h"
@ -50,22 +49,6 @@ int IcingaApplication::Main(void)
UpdatePidFile(GetPidPath());
if (!GetCertificateFile().IsEmpty() && !GetCAFile().IsEmpty()) {
/* set up SSL context */
shared_ptr<X509> cert = GetX509Certificate(GetCertificateFile());
String identity = GetCertificateCN(cert);
Log(LogInformation, "icinga", "My identity: " + identity);
EndpointManager::GetInstance()->SetIdentity(identity);
m_SSLContext = MakeSSLContext(GetCertificateFile(), GetCertificateFile(), GetCAFile());
EndpointManager::GetInstance()->SetSSLContext(m_SSLContext);
}
/* create the primary RPC listener */
if (!GetService().IsEmpty())
EndpointManager::GetInstance()->AddListener(GetService());
/* restore the previous program state */
DynamicObject::RestoreObjects(GetStatePath());
@ -104,34 +87,6 @@ IcingaApplication::Ptr IcingaApplication::GetInstance(void)
return static_pointer_cast<IcingaApplication>(Application::GetInstance());
}
String IcingaApplication::GetCertificateFile(void) const
{
ObjectLock olock(this);
return m_CertPath;
}
String IcingaApplication::GetCAFile(void) const
{
ObjectLock olock(this);
return m_CAPath;
}
String IcingaApplication::GetNode(void) const
{
ObjectLock olock(this);
return m_Node;
}
String IcingaApplication::GetService(void) const
{
ObjectLock olock(this);
return m_Service;
}
String IcingaApplication::GetPidPath(void) const
{
ObjectLock olock(this);
@ -146,10 +101,10 @@ String IcingaApplication::GetStatePath(void) const
{
ObjectLock olock(this);
if (m_PidPath.IsEmpty())
if (m_StatePath.IsEmpty())
return Application::GetLocalStateDir() + "/lib/icinga2/icinga2.state";
else
return m_PidPath;
return m_StatePath;
}
Dictionary::Ptr IcingaApplication::GetMacros(void) const
@ -166,13 +121,6 @@ double IcingaApplication::GetStartTime(void) const
return m_StartTime;
}
shared_ptr<SSL_CTX> IcingaApplication::GetSSLContext(void) const
{
ObjectLock olock(this);
return m_SSLContext;
}
bool IcingaApplication::ResolveMacro(const String& macro, const Dictionary::Ptr&, String *result) const
{
double now = Utility::GetTime();
@ -209,10 +157,6 @@ void IcingaApplication::InternalSerialize(const Dictionary::Ptr& bag, int attrib
DynamicObject::InternalSerialize(bag, attributeTypes);
if (attributeTypes & Attribute_Config) {
bag->Set("cert_path", m_CertPath);
bag->Set("ca_path", m_CAPath);
bag->Set("node", m_Node);
bag->Set("service", m_Service);
bag->Set("pid_path", m_PidPath);
bag->Set("state_path", m_StatePath);
bag->Set("macros", m_Macros);
@ -224,10 +168,6 @@ void IcingaApplication::InternalDeserialize(const Dictionary::Ptr& bag, int attr
DynamicObject::InternalDeserialize(bag, attributeTypes);
if (attributeTypes & Attribute_Config) {
m_CertPath = bag->Get("cert_path");
m_CAPath = bag->Get("ca_path");
m_Node = bag->Get("node");
m_Service = bag->Get("service");
m_PidPath = bag->Get("pid_path");
m_StatePath = bag->Get("state_path");
m_Macros = bag->Get("macros");

View File

@ -23,7 +23,6 @@
#include "icinga/i2-icinga.h"
#include "icinga/macroresolver.h"
#include "base/application.h"
#include "base/tlsutility.h"
namespace icinga
{
@ -43,14 +42,9 @@ public:
static IcingaApplication::Ptr GetInstance(void);
String GetCertificateFile(void) const;
String GetCAFile(void) const;
String GetNode(void) const;
String GetService(void) const;
String GetPidPath(void) const;
String GetStatePath(void) const;
Dictionary::Ptr GetMacros(void) const;
shared_ptr<SSL_CTX> GetSSLContext(void) const;
double GetStartTime(void) const;
@ -61,16 +55,10 @@ protected:
virtual void InternalDeserialize(const Dictionary::Ptr& bag, int attributeTypes);
private:
String m_CertPath;
String m_CAPath;
String m_Node;
String m_Service;
String m_PidPath;
String m_StatePath;
Dictionary::Ptr m_Macros;
shared_ptr<SSL_CTX> m_SSLContext;
double m_StartTime;
void DumpProgramState(void);

View File

@ -21,7 +21,6 @@
#include "icinga/notificationcommand.h"
#include "icinga/macroprocessor.h"
#include "icinga/service.h"
#include "remoting/endpointmanager.h"
#include "base/dynamictype.h"
#include "base/objectlock.h"
#include "base/logger_fwd.h"

View File

@ -590,8 +590,6 @@ void Service::ProcessCheckResult(const Dictionary::Ptr& cr)
cr->Set("vars_after", vars_after);
cr->Seal();
olock.Lock();
SetLastCheckResult(cr);
@ -749,7 +747,6 @@ void Service::ExecuteCheck(void)
checkInfo->Set("execution_end", Utility::GetTime());
checkInfo->Set("schedule_end", Utility::GetTime());
checkInfo->Seal();
if (result) {
if (!result->Contains("schedule_start"))

View File

@ -57,5 +57,4 @@ libido_la_LIBADD = \
$(BOOST_SYSTEM_LIB) \
${top_builddir}/lib/base/libbase.la \
${top_builddir}/lib/config/libconfig.la \
${top_builddir}/lib/remoting/libremoting.la \
${top_builddir}/lib/icinga/libicinga.la

View File

@ -27,6 +27,5 @@ libpython_la_LDFLAGS = \
libpython_la_LIBADD = \
$(BOOST_THREAD_LIB) \
${top_builddir}/lib/base/libbase.la \
${top_builddir}/lib/config/libconfig.la \
${top_builddir}/lib/remoting/libremoting.la
${top_builddir}/lib/config/libconfig.la
endif

View File

@ -1 +0,0 @@
remoting-type.cpp

View File

@ -1,411 +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 "remoting/endpointmanager.h"
#include "base/dynamictype.h"
#include "base/objectlock.h"
#include "base/logger_fwd.h"
#include "base/convert.h"
#include "base/utility.h"
#include "base/tlsutility.h"
#include "base/networkstream.h"
#include <boost/tuple/tuple.hpp>
#include <boost/foreach.hpp>
using namespace icinga;
/**
* Constructor for the EndpointManager class.
*/
EndpointManager::EndpointManager(void)
{
m_ReconnectTimer = boost::make_shared<Timer>();
m_ReconnectTimer->OnTimerExpired.connect(boost::bind(&EndpointManager::ReconnectTimerHandler, this));
m_ReconnectTimer->SetInterval(5);
m_ReconnectTimer->Start();
}
/**
* Sets the SSL context.
*
* @param sslContext The new SSL context.
*/
void EndpointManager::SetSSLContext(const shared_ptr<SSL_CTX>& sslContext)
{
ObjectLock olock(this);
m_SSLContext = sslContext;
}
/**
* Retrieves the SSL context.
*
* @returns The SSL context.
*/
shared_ptr<SSL_CTX> EndpointManager::GetSSLContext(void) const
{
ObjectLock olock(this);
return m_SSLContext;
}
/**
* Sets the identity of the endpoint manager. This identity is used when
* connecting to remote peers.
*
* @param identity The new identity.
*/
void EndpointManager::SetIdentity(const String& identity)
{
ObjectLock olock(this);
m_Identity = identity;
}
/**
* Retrieves the identity for the endpoint manager.
*
* @returns The identity.
*/
String EndpointManager::GetIdentity(void) const
{
ObjectLock olock(this);
return m_Identity;
}
/**
* Creates a new JSON-RPC listener on the specified port.
*
* @param service The port to listen on.
*/
void EndpointManager::AddListener(const String& service)
{
ObjectLock olock(this);
shared_ptr<SSL_CTX> sslContext = m_SSLContext;
if (!sslContext)
BOOST_THROW_EXCEPTION(std::logic_error("SSL context is required for AddListener()"));
std::ostringstream s;
s << "Adding new listener: port " << service;
Log(LogInformation, "icinga", s.str());
TcpSocket::Ptr server = boost::make_shared<TcpSocket>();
server->Bind(service, AF_INET6);
boost::thread thread(boost::bind(&EndpointManager::ListenerThreadProc, this, server));
thread.detach();
m_Servers.insert(server);
}
void EndpointManager::ListenerThreadProc(const Socket::Ptr& server)
{
server->Listen();
for (;;) {
Socket::Ptr client = server->Accept();
try {
NewClientHandler(client, TlsRoleServer);
} catch (const std::exception& ex) {
std::stringstream message;
message << "Error for new JSON-RPC socket: " << boost::diagnostic_information(ex);
Log(LogInformation, "remoting", message.str());
}
}
}
/**
* Creates a new JSON-RPC client and connects to the specified host and port.
*
* @param node The remote host.
* @param service The remote port.
*/
void EndpointManager::AddConnection(const String& node, const String& service) {
{
ObjectLock olock(this);
shared_ptr<SSL_CTX> sslContext = m_SSLContext;
if (!sslContext)
BOOST_THROW_EXCEPTION(std::logic_error("SSL context is required for AddConnection()"));
}
TcpSocket::Ptr client = boost::make_shared<TcpSocket>();
try {
client->Connect(node, service);
NewClientHandler(client, TlsRoleClient);
} catch (const std::exception& ex) {
Log(LogInformation, "remoting", "Could not connect to " + node + ":" + service + ": " + ex.what());
}
}
/**
* Processes a new client connection.
*
* @param client The new client.
*/
void EndpointManager::NewClientHandler(const Socket::Ptr& client, TlsRole role)
{
NetworkStream::Ptr netStream = boost::make_shared<NetworkStream>(client);
TlsStream::Ptr tlsStream = boost::make_shared<TlsStream>(netStream, role, m_SSLContext);
tlsStream->Handshake();
shared_ptr<X509> cert = tlsStream->GetPeerCertificate();
String identity = GetCertificateCN(cert);
Log(LogInformation, "icinga", "New client connection for identity '" + identity + "'");
Endpoint::Ptr endpoint = Endpoint::GetByName(identity);
if (!endpoint) {
Log(LogInformation, "remoting", "Closing endpoint '" + identity + "': No configuration available.");
return;
}
endpoint->SetClient(tlsStream);
}
///**
// * Sends an anonymous unicast message to the specified recipient.
// *
// * @param recipient The recipient of the message.
// * @param message The message.
// */
//void EndpointManager::SendUnicastMessage(const Endpoint::Ptr& recipient,
// const MessagePart& message)
//{
// SendUnicastMessage(Endpoint::Ptr(), recipient, message);
//}
///**
// * Sends a unicast message to the specified recipient.
// *
// * @param sender The sender of the message.
// * @param recipient The recipient of the message.
// * @param message The message.
// */
//void EndpointManager::SendUnicastMessage(const Endpoint::Ptr& sender,
// const Endpoint::Ptr& recipient, const MessagePart& message)
//{
// /* don't forward messages between non-local endpoints, assume that
// * anonymous senders (sender == null) are local */
//// if ((sender && !sender->IsLocal()) && !recipient->IsLocal())
//// return;
//
// if (ResponseMessage::IsResponseMessage(message))
// recipient->ProcessResponse(sender, message);
// else
// recipient->ProcessRequest(sender, message);
//}
///**
// * Sends a message to exactly one recipient out of all recipients who have a
// * subscription for the message's topic.
// *
// * @param sender The sender of the message.
// * @param message The message.
// */
//void EndpointManager::SendAnycastMessage(const Endpoint::Ptr& sender,
// const RequestMessage& message)
//{
// String method;
// if (!message.GetMethod(&method))
// BOOST_THROW_EXCEPTION(std::invalid_argument("Message is missing the 'method' property."));
//
// std::vector<Endpoint::Ptr> candidates;
//
// BOOST_FOREACH(const Endpoint::Ptr& endpoint, DynamicType::GetObjects<Endpoint>()) {
// /* don't forward messages between non-local endpoints */
//// if ((sender && !sender->IsLocal()) && !endpoint->IsLocal())
//// continue;
//
// if (endpoint->HasSubscription(method))
// candidates.push_back(endpoint);
// }
//
// if (candidates.empty())
// return;
//
// Endpoint::Ptr recipient = candidates[rand() % candidates.size()];
// SendUnicastMessage(sender, recipient, message);
//}
///**
// * Sends an anonymous message to all recipients who have a subscription for the
// * message's topic.
// *
// * @param message The message.
// */
//void EndpointManager::SendMulticastMessage(const RequestMessage& message)
//{
// SendMulticastMessage(Endpoint::Ptr(), message);
//}
///**
// * Sends a message to all recipients who have a subscription for the
// * message's topic.
// *
// * @param sender The sender of the message.
// * @param message The message.
// */
//void EndpointManager::SendBroadcastMessage(const Endpoint::Ptr& sender,
// const RequestMessage& message)
//{
// String method;
// if (!message.GetMethod(&method))
// BOOST_THROW_EXCEPTION(std::invalid_argument("Message is missing the 'method' property."));
//
// BOOST_FOREACH(const Endpoint::Ptr& recipient, DynamicType::GetObjects<Endpoint>()) {
// /* don't forward messages back to the sender */
// if (sender == recipient)
// continue;
//
// Log(LogDebug, "remoting", "Send multicast message using method " + method);
// if (recipient->HasSubscription(method))
// SendUnicastMessage(sender, recipient, message);
// }
//}
//void EndpointManager::SendAPIMessage(const Endpoint::Ptr& sender, const Endpoint::Ptr& recipient,
// RequestMessage& message,
// const EndpointManager::APICallback& callback, double timeout)
//{
// ObjectLock olock(this);
//
// m_NextMessageID++;
//
// String id = Convert::ToString(m_NextMessageID);
// message.SetID(id);
//
// PendingRequest pr;
// pr.Request = message;
// pr.Callback = callback;
// pr.Timeout = Utility::GetTime() + timeout;
//
// m_Requests[id] = pr;
//
// if (!recipient)
// SendAnycastMessage(sender, message);
// else
// SendUnicastMessage(sender, recipient, message);
//}
//
//bool EndpointManager::RequestTimeoutLessComparer(const std::pair<String, PendingRequest>& a,
// const std::pair<String, PendingRequest>& b)
//{
// return a.second.Timeout < b.second.Timeout;
//}
//
//void EndpointManager::SubscriptionTimerHandler(void)
//{
// Dictionary::Ptr subscriptions = boost::make_shared<Dictionary>();
//
// BOOST_FOREACH(const Endpoint::Ptr& endpoint, DynamicType::GetObjects<Endpoint>()) {
// /* don't copy subscriptions from non-local endpoints or the identity endpoint */
//// if (!endpoint->IsLocalEndpoint() || endpoint == m_Endpoint)
//// continue;
//
// Dictionary::Ptr endpointSubscriptions = endpoint->GetSubscriptions();
//
// if (endpointSubscriptions) {
// ObjectLock olock(endpointSubscriptions);
//
// String topic;
// BOOST_FOREACH(boost::tie(boost::tuples::ignore, topic), endpointSubscriptions) {
// subscriptions->Set(topic, topic);
// }
// }
// }
//
// subscriptions->Seal();
//
// if (m_Endpoint) {
// ObjectLock olock(m_Endpoint);
// m_Endpoint->SetSubscriptions(subscriptions);
// }
//}
void EndpointManager::ReconnectTimerHandler(void)
{
BOOST_FOREACH(const Endpoint::Ptr& endpoint, DynamicType::GetObjects<Endpoint>()) {
if (endpoint->IsConnected() || endpoint == m_Endpoint)
continue;
String host, port;
host = endpoint->GetHost();
port = endpoint->GetPort();
if (host.IsEmpty() || port.IsEmpty()) {
Log(LogWarning, "icinga", "Can't reconnect "
"to endpoint '" + endpoint->GetName() + "': No "
"host/port information.");
continue;
}
AddConnection(host, port);
}
}
//void EndpointManager::RequestTimerHandler(void)
//{
// ObjectLock olock(this);
//
// std::map<String, PendingRequest>::iterator it;
// for (it = m_Requests.begin(); it != m_Requests.end(); ++it) {
// if (it->second.HasTimedOut()) {
// it->second.Callback(Endpoint::Ptr(), it->second.Request,
// ResponseMessage(), true);
//
// m_Requests.erase(it);
//
// break;
// }
// }
//}
//void EndpointManager::ProcessResponseMessage(const Endpoint::Ptr& sender,
// const ResponseMessage& message)
//{
// ObjectLock olock(this);
//
// String id;
// if (!message.GetID(&id))
// BOOST_THROW_EXCEPTION(std::invalid_argument("Response message must have a message ID."));
//
// std::map<String, PendingRequest>::iterator it;
// it = m_Requests.find(id);
//
// if (it == m_Requests.end())
// return;
//
// it->second.Callback(sender, it->second.Request, message, false);
//
// m_Requests.erase(it);
//}
EndpointManager *EndpointManager::GetInstance(void)
{
return Singleton<EndpointManager>::GetInstance();
}

View File

@ -1,38 +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 I2REMOTING_H
#define I2REMOTING_H
/**
* @defgroup remoting Remoting library
*
* Implements server and client classes for the JSON-RPC protocol. Also
* supports endpoint-based communication using messages.
*/
#include "base/i2-base.h"
#ifdef I2_REMOTING_BUILD
# define I2_REMOTING_API I2_EXPORT
#else /* I2_REMOTING_BUILD */
# define I2_REMOTING_API I2_IMPORT
#endif /* I2_REMOTING_BUILD */
#endif /* I2REMOTING_H */

View File

@ -1,58 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="responsemessage.cpp">
<Filter>Quelldateien</Filter>
</ClCompile>
<ClCompile Include="messagepart.cpp">
<Filter>Quelldateien</Filter>
</ClCompile>
<ClCompile Include="requestmessage.cpp">
<Filter>Quelldateien</Filter>
</ClCompile>
<ClCompile Include="endpoint.cpp">
<Filter>Quelldateien</Filter>
</ClCompile>
<ClCompile Include="endpointmanager.cpp">
<Filter>Quelldateien</Filter>
</ClCompile>
<ClCompile Include="remoting-type.cpp">
<Filter>Quelldateien</Filter>
</ClCompile>
<ClCompile Include="jsonrpc.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="messagepart.h">
<Filter>Headerdateien</Filter>
</ClInclude>
<ClInclude Include="requestmessage.h">
<Filter>Headerdateien</Filter>
</ClInclude>
<ClInclude Include="responsemessage.h">
<Filter>Headerdateien</Filter>
</ClInclude>
<ClInclude Include="i2-remoting.h">
<Filter>Headerdateien</Filter>
</ClInclude>
<ClInclude Include="endpoint.h">
<Filter>Headerdateien</Filter>
</ClInclude>
<ClInclude Include="endpointmanager.h">
<Filter>Headerdateien</Filter>
</ClInclude>
<ClInclude Include="jsonrpc.h" />
</ItemGroup>
<ItemGroup>
<Filter Include="Headerdateien">
<UniqueIdentifier>{796f79ec-5628-4c91-9e2b-3d603ab2acfc}</UniqueIdentifier>
</Filter>
<Filter Include="Quelldateien">
<UniqueIdentifier>{0457f937-d12b-4328-818b-77359de2425f}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="remoting-type.conf">
<Filter>Quelldateien</Filter>
</CustomBuild>
</ItemGroup>
</Project>