Refactored subscription code in preparation for a centralized broker/discovery component.

This commit is contained in:
Gunnar Beutner 2012-04-30 15:30:45 +02:00
parent 0c59c675be
commit c8a5343fe5
38 changed files with 680 additions and 498 deletions

View File

@ -113,3 +113,45 @@ DictionaryIterator Dictionary::End(void)
{
return m_Data.end();
}
long Dictionary::GetLength(void) const
{
return m_Data.size();
}
void Dictionary::AddUnnamedProperty(const Variant& value)
{
map<string, Variant>::const_iterator it;
string key;
do {
long index = GetLength();
stringstream s;
s << "_" << GetLength();
key = s.str();
it = m_Data.find(key);
} while (it != m_Data.end());
m_Data[key] = value;
}
void Dictionary::AddUnnamedPropertyString(const string& value)
{
AddUnnamedProperty(Variant(value));
}
void Dictionary::AddUnnamedPropertyInteger(long value)
{
AddUnnamedProperty(Variant(value));
}
void Dictionary::AddUnnamedPropertyDictionary(const Dictionary::Ptr& value)
{
AddUnnamedProperty(Variant(value));
}
void Dictionary::AddUnnamedPropertyObject(const Object::Ptr& value)
{
AddUnnamedProperty(Variant(value));
}

View File

@ -41,6 +41,14 @@ public:
DictionaryIterator Begin(void);
DictionaryIterator End(void);
void AddUnnamedProperty(const Variant& value);
void AddUnnamedPropertyString(const string& value);
void AddUnnamedPropertyInteger(long value);
void AddUnnamedPropertyDictionary(const Dictionary::Ptr& value);
void AddUnnamedPropertyObject(const Object::Ptr& value);
long GetLength(void) const;
Event<PropertyChangedEventArgs> OnPropertyChanged;
};

View File

@ -3,4 +3,5 @@
SUBDIRS = configfile \
configrpc \
demo
demo \
discovery

View File

@ -17,9 +17,6 @@ void DemoComponent::Start(void)
EndpointManager::Ptr endpointManager = GetIcingaApplication()->GetEndpointManager();
endpointManager->RegisterEndpoint(m_DemoEndpoint);
endpointManager->OnNewEndpoint += bind_weak(&DemoComponent::NewEndpointHandler, shared_from_this());
endpointManager->ForeachEndpoint(bind(&DemoComponent::NewEndpointHandler, this, _1));
m_DemoTimer = make_shared<Timer>();
m_DemoTimer->SetInterval(5);
m_DemoTimer->OnTimerExpired += bind_weak(&DemoComponent::DemoTimerHandler, shared_from_this());
@ -36,15 +33,6 @@ void DemoComponent::Stop(void)
}
}
int DemoComponent::NewEndpointHandler(const NewEndpointEventArgs& neea)
{
/* Allow sending/receiving demo messages without authentication */
neea.Endpoint->AddAllowedMethodSinkPrefix("demo::");
neea.Endpoint->AddAllowedMethodSourcePrefix("demo::");
return 0;
}
int DemoComponent::DemoTimerHandler(const TimerEventArgs& tea)
{
Application::Log("Sending multicast 'hello world' message.");

View File

@ -11,7 +11,6 @@ private:
VirtualEndpoint::Ptr m_DemoEndpoint;
int DemoTimerHandler(const TimerEventArgs& tea);
int NewEndpointHandler(const NewEndpointEventArgs& neea);
int HelloWorldRequestHandler(const NewRequestEventArgs& nrea);
public:

View File

@ -0,0 +1,22 @@
## Process this file with automake to produce Makefile.in
pkglib_LTLIBRARIES = \
discovery.la
discovery_la_SOURCES = \
discoverycomponent.cpp \
discoverycomponent.h \
discoverymessage.cpp \
discoverymessage.h \
i2-discovery.h
discovery_la_CXXFLAGS = -I${top_srcdir}/base \
-I${top_srcdir}/jsonrpc \
-I${top_srcdir}/cJSON \
-I${top_srcdir}/icinga
discovery_la_LDFLAGS = -module -version-info 0:0:0 -no-undefined -pthread
discovery_la_LIBADD = ${top_builddir}/base/libbase.la \
${top_builddir}/jsonrpc/libjsonrpc.la \
${top_builddir}/cJSON/libcJSON.la \
${top_builddir}/icinga/libicinga.la

View File

@ -0,0 +1,94 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{EAD41628-BB96-4F99-9070-8A9676801295}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>discovery</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(SolutionDir)\base;$(SolutionDir)\jsonrpc;$(SolutionDir)\icinga;$(IncludePath)</IncludePath>
<LibraryPath>$(OutDir);$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>$(SolutionDir)\base;$(SolutionDir)\jsonrpc;$(SolutionDir)\icinga;$(IncludePath)</IncludePath>
<LibraryPath>$(OutDir);$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;DISCOVERY_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>base.lib;jsonrpc.lib;icinga.lib;cJSON.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;DISCOVERY_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>base.lib;jsonrpc.lib;icinga.lib;cJSON.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="discoverycomponent.cpp" />
<ClCompile Include="discoverymessage.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="discoverycomponent.h" />
<ClInclude Include="discoverymessage.h" />
<ClInclude Include="i2-discovery.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,287 @@
#include "i2-discovery.h"
using namespace icinga;
string DiscoveryComponent::GetName(void) const
{
return "discoverycomponent";
}
void DiscoveryComponent::Start(void)
{
m_DiscoveryEndpoint = make_shared<VirtualEndpoint>();
long isBroker = 0;
GetConfig()->GetPropertyInteger("broker", &isBroker);
m_Broker = (isBroker != 0);
if (IsBroker()) {
m_DiscoveryEndpoint->RegisterMethodSource("discovery::NewComponent");
m_DiscoveryEndpoint->RegisterMethodHandler("discovery::RegisterComponent",
bind_weak(&DiscoveryComponent::RegisterComponentMessageHandler, shared_from_this()));
}
m_DiscoveryEndpoint->RegisterMethodSource("discovery::RegisterComponent");
m_DiscoveryEndpoint->RegisterMethodHandler("discovery::NewComponent",
bind_weak(&DiscoveryComponent::NewComponentMessageHandler, shared_from_this()));
GetEndpointManager()->ForeachEndpoint(bind(&DiscoveryComponent::NewEndpointHandler, this, _1));
GetEndpointManager()->OnNewEndpoint += bind_weak(&DiscoveryComponent::NewEndpointHandler, shared_from_this());
GetEndpointManager()->RegisterEndpoint(m_DiscoveryEndpoint);
}
void DiscoveryComponent::Stop(void)
{
EndpointManager::Ptr mgr = GetEndpointManager();
if (mgr)
mgr->UnregisterEndpoint(m_DiscoveryEndpoint);
}
int DiscoveryComponent::CheckExistingEndpoint(Endpoint::Ptr endpoint, const NewEndpointEventArgs& neea)
{
if (endpoint == neea.Endpoint)
return 0;
if (!neea.Endpoint->IsConnected())
return 0;
if (endpoint->GetIdentity() == neea.Endpoint->GetIdentity()) {
Application::Log("Detected duplicate identity (" + endpoint->GetIdentity() + " - Disconnecting old endpoint.");
neea.Endpoint->Stop();
GetEndpointManager()->UnregisterEndpoint(neea.Endpoint);
}
return 0;
}
int DiscoveryComponent::NewEndpointHandler(const NewEndpointEventArgs& neea)
{
neea.Endpoint->OnIdentityChanged += bind_weak(&DiscoveryComponent::NewIdentityHandler, shared_from_this());
/* accept discovery::RegisterComponent messages from any endpoint */
neea.Endpoint->RegisterMethodSource("discovery::RegisterComponent");
return 0;
}
int DiscoveryComponent::DiscoverySinkHandler(const NewMethodEventArgs& nmea, ComponentDiscoveryInfo::Ptr info) const
{
info->SubscribedMethods.insert(nmea.Method);
return 0;
}
int DiscoveryComponent::DiscoverySourceHandler(const NewMethodEventArgs& nmea, ComponentDiscoveryInfo::Ptr info) const
{
info->PublishedMethods.insert(nmea.Method);
return 0;
}
int DiscoveryComponent::DiscoveryEndpointHandler(const NewEndpointEventArgs& neea, ComponentDiscoveryInfo::Ptr info) const
{
neea.Endpoint->ForeachMethodSink(bind(&DiscoveryComponent::DiscoverySinkHandler, this, _1, info));
neea.Endpoint->ForeachMethodSource(bind(&DiscoveryComponent::DiscoverySourceHandler, this, _1, info));
return 0;
}
bool DiscoveryComponent::GetComponentDiscoveryInfo(string component, ComponentDiscoveryInfo::Ptr *info) const
{
if (component == GetEndpointManager()->GetIdentity()) {
/* Build fake discovery info for ourselves */
*info = make_shared<ComponentDiscoveryInfo>();
GetEndpointManager()->ForeachEndpoint(bind(&DiscoveryComponent::DiscoveryEndpointHandler, this, _1, *info));
(*info)->Node = GetIcingaApplication()->GetNode();
(*info)->Service = GetIcingaApplication()->GetService();
return true;
}
map<string, ComponentDiscoveryInfo::Ptr>::const_iterator i;
i = m_Components.find(component);
if (i == m_Components.end())
return false;
*info = i->second;
return true;
}
bool DiscoveryComponent::IsBroker(void) const
{
return m_Broker;
}
int DiscoveryComponent::NewIdentityHandler(const EventArgs& ea)
{
Endpoint::Ptr endpoint = static_pointer_cast<Endpoint>(ea.Source);
string identity = endpoint->GetIdentity();
if (identity == GetEndpointManager()->GetIdentity()) {
Application::Log("Detected loop-back connection - Disconnecting endpoint.");
endpoint->Stop();
GetEndpointManager()->UnregisterEndpoint(endpoint);
return 0;
}
GetEndpointManager()->ForeachEndpoint(bind(&DiscoveryComponent::CheckExistingEndpoint, this, endpoint, _1));
// we assume the other component _always_ wants
// discovery::RegisterComponent messages from us
endpoint->RegisterMethodSink("discovery::RegisterComponent");
// send a discovery::RegisterComponent message, if the
// other component is a broker this makes sure
// the broker knows about our message types
SendDiscoveryMessage("discovery::RegisterComponent", GetEndpointManager()->GetIdentity(), endpoint);
map<string, ComponentDiscoveryInfo::Ptr>::iterator i;
if (IsBroker()) {
// we assume the other component _always_ wants
// discovery::NewComponent messages from us
endpoint->RegisterMethodSink("discovery::NewComponent");
// send discovery::NewComponent message for ourselves
SendDiscoveryMessage("discovery::NewComponent", GetEndpointManager()->GetIdentity(), endpoint);
// send discovery::NewComponent messages for all components
// we know about
for (i = m_Components.begin(); i != m_Components.end(); i++) {
SendDiscoveryMessage("discovery::NewComponent", i->first, endpoint);
}
}
// check if we already know the other component
i = m_Components.find(endpoint->GetIdentity());
if (i == m_Components.end()) {
// we don't know the other component yet, so
// wait until we get a discovery::NewComponent message
// from a broker
return 0;
}
// TODO: send discovery::Welcome message
// TODO: add subscriptions/provides to this endpoint
return 0;
}
void DiscoveryComponent::SendDiscoveryMessage(string method, string identity, Endpoint::Ptr recipient)
{
JsonRpcRequest request;
request.SetMethod(method);
DiscoveryMessage params;
request.SetParams(params);
params.SetIdentity(identity);
Message subscriptions;
params.SetSubscribes(subscriptions);
Message publications;
params.SetProvides(publications);
ComponentDiscoveryInfo::Ptr info;
if (!GetComponentDiscoveryInfo(identity, &info))
return;
if (!info->Node.empty() && !info->Service.empty()) {
params.SetPropertyString("node", info->Node);
params.SetPropertyString("service", info->Service);
}
set<string>::iterator i;
for (i = info->PublishedMethods.begin(); i != info->PublishedMethods.end(); i++)
publications.AddUnnamedPropertyString(*i);
for (i = info->SubscribedMethods.begin(); i != info->SubscribedMethods.end(); i++)
subscriptions.AddUnnamedPropertyString(*i);
if (recipient)
GetEndpointManager()->SendUnicastRequest(m_DiscoveryEndpoint, recipient, request);
else
GetEndpointManager()->SendMulticastRequest(m_DiscoveryEndpoint, request);
}
void DiscoveryComponent::ProcessDiscoveryMessage(string identity, DiscoveryMessage message)
{
ComponentDiscoveryInfo::Ptr info = make_shared<ComponentDiscoveryInfo>();
}
int DiscoveryComponent::NewComponentMessageHandler(const NewRequestEventArgs& nrea)
{
/*Message message;
nrea.Request.GetParams(&message);
ProcessDiscoveryMessage(message.GetPropertyString(, DiscoveryMessage(message));*/
return 0;
}
int DiscoveryComponent::RegisterComponentMessageHandler(const NewRequestEventArgs& nrea)
{
Message message;
nrea.Request.GetParams(&message);
ProcessDiscoveryMessage(nrea.Sender->GetIdentity(), DiscoveryMessage(message));
return 0;
}
void DiscoveryComponent::AddSubscribedMethod(string identity, string method)
{
ComponentDiscoveryInfo::Ptr info;
if (!GetComponentDiscoveryInfo(identity, &info))
return;
info->SubscribedMethods.insert(method);
}
bool DiscoveryComponent::IsSubscribedMethod(string identity, string method) const
{
if (GetEndpointManager()->GetIdentity() == identity)
return true;
ComponentDiscoveryInfo::Ptr info;
if (!GetComponentDiscoveryInfo(identity, &info))
return false;
set<string>::const_iterator i;
i = info->SubscribedMethods.find(method);
return (i != info->SubscribedMethods.end());
}
void DiscoveryComponent::AddPublishedMethod(string identity, string method)
{
ComponentDiscoveryInfo::Ptr info;
if (!GetComponentDiscoveryInfo(identity, &info))
return;
info->PublishedMethods.insert(method);
}
bool DiscoveryComponent::IsPublishedMethod(string identity, string method) const
{
if (GetEndpointManager()->GetIdentity() == identity)
return true;
ComponentDiscoveryInfo::Ptr info;
if (!GetComponentDiscoveryInfo(identity, &info))
return false;
set<string>::const_iterator i;
i = info->PublishedMethods.find(method);
return (i != info->PublishedMethods.end());
}
EXPORT_COMPONENT(DiscoveryComponent);

View File

@ -0,0 +1,60 @@
#ifndef DISCOVERYCOMPONENT_H
#define DISCOVERYCOMPONENT_H
namespace icinga
{
class ComponentDiscoveryInfo : public Object
{
public:
typedef shared_ptr<ComponentDiscoveryInfo> Ptr;
typedef weak_ptr<ComponentDiscoveryInfo> WeakPtr;
string Node;
string Service;
set<string> SubscribedMethods;
set<string> PublishedMethods;
};
class DiscoveryComponent : public IcingaComponent
{
private:
VirtualEndpoint::Ptr m_DiscoveryEndpoint;
map<string, ComponentDiscoveryInfo::Ptr> m_Components;
bool m_Broker;
int NewEndpointHandler(const NewEndpointEventArgs& neea);
int NewIdentityHandler(const EventArgs& ea);
int NewComponentMessageHandler(const NewRequestEventArgs& nrea);
int RegisterComponentMessageHandler(const NewRequestEventArgs& nrea);
void SendDiscoveryMessage(string method, string identity, Endpoint::Ptr recipient);
void ProcessDiscoveryMessage(string identity, DiscoveryMessage message);
bool GetComponentDiscoveryInfo(string component, ComponentDiscoveryInfo::Ptr *info) const;
int CheckExistingEndpoint(Endpoint::Ptr endpoint, const NewEndpointEventArgs& neea);
int DiscoveryEndpointHandler(const NewEndpointEventArgs& neea, ComponentDiscoveryInfo::Ptr info) const;
int DiscoverySinkHandler(const NewMethodEventArgs& nmea, ComponentDiscoveryInfo::Ptr info) const;
int DiscoverySourceHandler(const NewMethodEventArgs& nmea, ComponentDiscoveryInfo::Ptr info) const;
bool IsBroker(void) const;
public:
virtual string GetName(void) const;
virtual void Start(void);
virtual void Stop(void);
void AddSubscribedMethod(string identity, string method);
bool IsSubscribedMethod(string identity, string method) const;
void AddPublishedMethod(string identity, string method);
bool IsPublishedMethod(string identity, string method) const;
};
}
#endif /* DISCOVERYCOMPONENT_H */

View File

@ -0,0 +1,3 @@
#include "i2-discovery.h"
using namespace icinga;

View File

@ -0,0 +1,47 @@
#ifndef DISCOVERYMESSAGE_H
#define DISCOVERYMESSAGE_H
namespace icinga
{
class DiscoveryMessage : public Message
{
public:
DiscoveryMessage(void) : Message() { }
DiscoveryMessage(const Message& message) : Message(message) { }
inline bool GetIdentity(string *value) const
{
return GetPropertyString("identity", value);
}
inline void SetIdentity(const string& value)
{
SetPropertyString("identity", value);
}
inline bool GetSubscribes(Message *value) const
{
return GetPropertyMessage("subscribes", value);
}
inline void SetSubscribes(Message value)
{
SetPropertyMessage("subscribes", value);
}
inline bool GetProvides(Message *value) const
{
return GetPropertyMessage("provides", value);
}
inline void SetProvides(Message value)
{
SetPropertyMessage("provides", value);
}
};
}
#endif /* SUBSCRIPTIONMESSAGE_H */

View File

@ -0,0 +1,11 @@
#ifndef I2DISCOVERY_H
#define I2DISCOVERY_H
#include <i2-base.h>
#include <i2-jsonrpc.h>
#include <i2-icinga.h>
#include "discoverymessage.h"
#include "discoverycomponent.h"
#endif /* I2DISCOVERY_H */

View File

@ -52,6 +52,7 @@ components/Makefile
components/configfile/Makefile
components/configrpc/Makefile
components/demo/Makefile
components/discovery/Makefile
icinga/Makefile
icinga-app/Makefile
jsonrpc/Makefile

View File

@ -3,16 +3,22 @@
"icinga": {
"privkey": "icinga-c1.key",
"pubkey": "icinga-c1.crt",
"cakey": "ca.crt"
"cakey": "ca.crt",
"node": "10.0.10.3",
"service": "7777"
}
},
"component": {
"configrpc": { "replicate": "0", "configSource": "1" },
"demo": { "replicate": "0" }
"demo": { "replicate": "0" },
"discovery": { "replicate": "0", "broker": "1" }
},
"rpclistener": {
"kekslistener": { "replicate": "0", "port": "7777" }
},
"rpcconnection": {
"foo": { "replicate": "0", "hostname": "10.0.10.3", "port": "7777" }
},
"host": {
"localhost": { "ipaddr": "127.0.0.1" }
}

View File

@ -19,6 +19,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "icinga", "icinga\icinga.vcx
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "icinga-app", "icinga-app\icinga-app.vcxproj", "{BE412865-FEBA-4259-AD41-58950D1F5432}"
ProjectSection(ProjectDependencies) = postProject
{EAD41628-BB96-4F99-9070-8A9676801295} = {EAD41628-BB96-4F99-9070-8A9676801295}
{2E6C1133-730F-4875-A72C-B455B1DD4C5C} = {2E6C1133-730F-4875-A72C-B455B1DD4C5C}
{697C6D7E-3109-484C-A7AF-384D28711610} = {697C6D7E-3109-484C-A7AF-384D28711610}
{E58F1DA7-B723-412B-B2B7-7FF58E2A944E} = {E58F1DA7-B723-412B-B2B7-7FF58E2A944E}
@ -40,6 +41,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo", "components\demo\dem
{C1FC77E1-04A4-481B-A78B-2F7AF489C2F8} = {C1FC77E1-04A4-481B-A78B-2F7AF489C2F8}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "discovery", "components\discovery\discovery.vcxproj", "{EAD41628-BB96-4F99-9070-8A9676801295}"
ProjectSection(ProjectDependencies) = postProject
{C1FC77E1-04A4-481B-A78B-2F7AF489C2F8} = {C1FC77E1-04A4-481B-A78B-2F7AF489C2F8}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@ -78,6 +84,10 @@ Global
{2E6C1133-730F-4875-A72C-B455B1DD4C5C}.Debug|Win32.Build.0 = Debug|Win32
{2E6C1133-730F-4875-A72C-B455B1DD4C5C}.Release|Win32.ActiveCfg = Release|Win32
{2E6C1133-730F-4875-A72C-B455B1DD4C5C}.Release|Win32.Build.0 = Release|Win32
{EAD41628-BB96-4F99-9070-8A9676801295}.Debug|Win32.ActiveCfg = Debug|Win32
{EAD41628-BB96-4F99-9070-8A9676801295}.Debug|Win32.Build.0 = Debug|Win32
{EAD41628-BB96-4F99-9070-8A9676801295}.Release|Win32.ActiveCfg = Release|Win32
{EAD41628-BB96-4F99-9070-8A9676801295}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -5,8 +5,6 @@ pkglib_LTLIBRARIES = \
libicinga.la
libicinga_la_SOURCES = \
discoverycomponent.cpp \
discoverycomponent.h \
endpoint.cpp \
endpoint.h \
endpointmanager.cpp \
@ -15,15 +13,9 @@ libicinga_la_SOURCES = \
icingaapplication.h \
icingacomponent.cpp \
icingacomponent.h \
identitymessage.cpp \
identitymessage.h \
i2-icinga.h \
jsonrpcendpoint.cpp \
jsonrpcendpoint.h \
subscriptioncomponent.cpp \
subscriptioncomponent.h \
subscriptionmessage.cpp \
subscriptionmessage.h \
virtualendpoint.cpp \
virtualendpoint.h

View File

@ -1,77 +0,0 @@
#include "i2-icinga.h"
using namespace icinga;
string DiscoveryComponent::GetName(void) const
{
return "discoverycomponent";
}
void DiscoveryComponent::Start(void)
{
m_DiscoveryEndpoint = make_shared<VirtualEndpoint>();
m_DiscoveryEndpoint->RegisterMethodHandler("message::Welcome",
bind_weak(&DiscoveryComponent::WelcomeMessageHandler, shared_from_this()));
m_DiscoveryEndpoint->RegisterMethodSource("discovery::PeerAvailable");
m_DiscoveryEndpoint->RegisterMethodHandler("discovery::GetPeers",
bind_weak(&DiscoveryComponent::GetPeersMessageHandler, shared_from_this()));
GetEndpointManager()->RegisterEndpoint(m_DiscoveryEndpoint);
}
void DiscoveryComponent::Stop(void)
{
EndpointManager::Ptr mgr = GetEndpointManager();
if (mgr)
mgr->UnregisterEndpoint(m_DiscoveryEndpoint);
}
int DiscoveryComponent::CheckExistingEndpoint(Endpoint::Ptr endpoint, const NewEndpointEventArgs& neea)
{
if (endpoint == neea.Endpoint)
return 0;
if (!neea.Endpoint->IsConnected())
return 0;
if (endpoint->GetIdentity() == neea.Endpoint->GetIdentity()) {
Application::Log("Detected duplicate identity (" + endpoint->GetIdentity() + " - Disconnecting old endpoint.");
neea.Endpoint->Stop();
GetEndpointManager()->UnregisterEndpoint(neea.Endpoint);
}
return 0;
}
int DiscoveryComponent::WelcomeMessageHandler(const NewRequestEventArgs& neea)
{
if (neea.Sender->GetIdentity() == GetEndpointManager()->GetIdentity()) {
Application::Log("Detected loop-back connection - Disconnecting endpoint.");
neea.Sender->Stop();
GetEndpointManager()->UnregisterEndpoint(neea.Sender);
return 0;
}
GetEndpointManager()->ForeachEndpoint(bind(&DiscoveryComponent::CheckExistingEndpoint, this, neea.Sender, _1));
JsonRpcRequest request;
request.SetMethod("discovery::GetPeers");
GetEndpointManager()->SendUnicastRequest(m_DiscoveryEndpoint, neea.Sender, request);
/* TODO: send information about this client to all other clients */
/* TODO: send stored events for this client */
return 0;
}
int DiscoveryComponent::GetPeersMessageHandler(const NewRequestEventArgs& nrea)
{
/* TODO: send information about all available clients to this client */
return 0;
}

View File

@ -1,27 +0,0 @@
#ifndef DISCOVERYCOMPONENT_H
#define DISCOVERYCOMPONENT_H
namespace icinga
{
class DiscoveryComponent : public IcingaComponent
{
private:
VirtualEndpoint::Ptr m_DiscoveryEndpoint;
IcingaApplication::Ptr GetIcingaApplication(void) const;
int WelcomeMessageHandler(const NewRequestEventArgs& neea);
int GetPeersMessageHandler(const NewRequestEventArgs& nrea);
int CheckExistingEndpoint(Endpoint::Ptr endpoint, const NewEndpointEventArgs& neea);
public:
virtual string GetName(void) const;
virtual void Start(void);
virtual void Stop(void);
};
}
#endif /* DISCOVERYCOMPONENT_H */

View File

@ -68,7 +68,7 @@ void Endpoint::UnregisterMethodSource(string method)
bool Endpoint::IsMethodSource(string method) const
{
return (m_MethodSources.find(method) != m_MethodSinks.end());
return (m_MethodSources.find(method) != m_MethodSources.end());
}
void Endpoint::ForeachMethodSource(function<int (const NewMethodEventArgs&)> callback)
@ -100,3 +100,23 @@ int Endpoint::CountMethodSources(void) const
{
return m_MethodSources.size();
}
set<string>::const_iterator Endpoint::BeginSinks(void) const
{
return m_MethodSinks.begin();
}
set<string>::const_iterator Endpoint::EndSinks(void) const
{
return m_MethodSinks.end();
}
set<string>::const_iterator Endpoint::BeginSources(void) const
{
return m_MethodSources.begin();
}
set<string>::const_iterator Endpoint::EndSources(void) const
{
return m_MethodSources.end();
}

View File

@ -41,13 +41,6 @@ public:
void UnregisterMethodSource(string method);
bool IsMethodSource(string method) const;
virtual void AddAllowedMethodSinkPrefix(string method) = 0;
virtual void RemoveAllowedMethodSinkPrefix(string method) = 0;
virtual bool IsAllowedMethodSink(string method) const = 0;
virtual void AddAllowedMethodSourcePrefix(string method) = 0;
virtual void RemoveAllowedMethodSourcePrefix(string method) = 0;
virtual bool IsAllowedMethodSource(string method) const = 0;
virtual bool IsLocal(void) const = 0;
virtual bool IsConnected(void) const = 0;
@ -68,7 +61,14 @@ public:
int CountMethodSinks(void) const;
int CountMethodSources(void) const;
set<string>::const_iterator BeginSinks(void) const;
set<string>::const_iterator EndSinks(void) const;
set<string>::const_iterator BeginSources(void) const;
set<string>::const_iterator EndSources(void) const;
Event<EventArgs> OnIdentityChanged;
Event<EventArgs> OnSessionEstablished;
};
}

View File

@ -79,12 +79,6 @@ void EndpointManager::RegisterEndpoint(Endpoint::Ptr endpoint)
endpoint->SetEndpointManager(static_pointer_cast<EndpointManager>(shared_from_this()));
m_Endpoints.push_front(endpoint);
endpoint->OnNewMethodSink += bind_weak(&EndpointManager::NewMethodSinkHandler, shared_from_this());
endpoint->ForeachMethodSink(bind(&EndpointManager::NewMethodSinkHandler, this, _1));
endpoint->OnNewMethodSource += bind_weak(&EndpointManager::NewMethodSourceHandler, shared_from_this());
endpoint->ForeachMethodSource(bind(&EndpointManager::NewMethodSourceHandler, this, _1));
NewEndpointEventArgs neea;
neea.Source = shared_from_this();
neea.Endpoint = endpoint;
@ -109,7 +103,7 @@ void EndpointManager::SendUnicastRequest(Endpoint::Ptr sender, Endpoint::Ptr rec
if (!request.GetMethod(&method))
throw InvalidArgumentException("Missing 'method' parameter.");
if (recipient->IsMethodSink(method) && recipient->IsAllowedMethodSink(method))
if (recipient->IsMethodSink(method))
recipient->ProcessRequest(sender, request);
}
@ -136,44 +130,6 @@ void EndpointManager::SendMulticastRequest(Endpoint::Ptr sender, const JsonRpcRe
}
}
int EndpointManager::NewMethodSinkHandler(const NewMethodEventArgs& ea)
{
Endpoint::Ptr sender = static_pointer_cast<Endpoint>(ea.Source);
if (!sender->IsLocal())
return 0;
JsonRpcRequest request;
request.SetMethod("message::Subscribe");
SubscriptionMessage subscriptionMessage;
subscriptionMessage.SetMethod(ea.Method);
request.SetParams(subscriptionMessage);
SendMulticastRequest(sender, request);
return 0;
}
int EndpointManager::NewMethodSourceHandler(const NewMethodEventArgs& ea)
{
Endpoint::Ptr sender = static_pointer_cast<Endpoint>(ea.Source);
if (!sender->IsLocal())
return 0;
JsonRpcRequest request;
request.SetMethod("message::Provide");
SubscriptionMessage subscriptionMessage;
subscriptionMessage.SetMethod(ea.Method);
request.SetParams(subscriptionMessage);
SendMulticastRequest(sender, request);
return 0;
}
void EndpointManager::ForeachEndpoint(function<int (const NewEndpointEventArgs&)> callback)
{
NewEndpointEventArgs neea;

View File

@ -22,9 +22,6 @@ class I2_ICINGA_API EndpointManager : public Object
int NewClientHandler(const NewClientEventArgs& ncea);
int NewMethodSinkHandler(const NewMethodEventArgs& ea);
int NewMethodSourceHandler(const NewMethodEventArgs& ea);
public:
typedef shared_ptr<EndpointManager> Ptr;
typedef weak_ptr<EndpointManager> WeakPtr;

View File

@ -17,9 +17,5 @@
#include "endpointmanager.h"
#include "icingaapplication.h"
#include "icingacomponent.h"
#include "subscriptioncomponent.h"
#include "subscriptionmessage.h"
#include "identitymessage.h"
#include "discoverycomponent.h"
#endif /* I2ICINGA_H */

View File

@ -11,28 +11,20 @@
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="discoverycomponent.cpp" />
<ClCompile Include="endpoint.cpp" />
<ClCompile Include="endpointmanager.cpp" />
<ClCompile Include="icingaapplication.cpp" />
<ClCompile Include="icingacomponent.cpp" />
<ClCompile Include="identitymessage.cpp" />
<ClCompile Include="jsonrpcendpoint.cpp" />
<ClCompile Include="subscriptioncomponent.cpp" />
<ClCompile Include="subscriptionmessage.cpp" />
<ClCompile Include="virtualendpoint.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="discoverycomponent.h" />
<ClInclude Include="endpoint.h" />
<ClInclude Include="endpointmanager.h" />
<ClInclude Include="i2-icinga.h" />
<ClInclude Include="icingaapplication.h" />
<ClInclude Include="icingacomponent.h" />
<ClInclude Include="identitymessage.h" />
<ClInclude Include="jsonrpcendpoint.h" />
<ClInclude Include="subscriptioncomponent.h" />
<ClInclude Include="subscriptionmessage.h" />
<ClInclude Include="virtualendpoint.h" />
</ItemGroup>
<PropertyGroup Label="Globals">

View File

@ -79,14 +79,6 @@ int IcingaApplication::Main(const vector<string>& args)
connectionCollection->ForEachObject(NewRpcConnectionHandler);
connectionCollection->OnObjectRemoved += bind_weak(&IcingaApplication::DeletedRpcConnectionHandler, shared_from_this());
/* load the subscription component */
SubscriptionComponent::Ptr subscriptionComponent = make_shared<SubscriptionComponent>();
RegisterComponent(subscriptionComponent);
/* load the discovery component */
DiscoveryComponent::Ptr discoveryComponent = make_shared<DiscoveryComponent>();
RegisterComponent(discoveryComponent);
RunEventLoop();
return EXIT_SUCCESS;
@ -154,6 +146,14 @@ int IcingaApplication::NewIcingaConfigHandler(const EventArgs& ea)
if (object->GetPropertyString("cakey", &cakey))
SetCAKeyFile(cakey);
string node;
if (object->GetPropertyString("node", &node))
SetNode(node);
string service;
if (object->GetPropertyString("service", &service))
SetService(service);
return 0;
}
@ -256,3 +256,23 @@ string IcingaApplication::GetCAKeyFile(void) const
{
return m_CAKeyFile;
}
void IcingaApplication::SetNode(string node)
{
m_Node = node;
}
string IcingaApplication::GetNode(void) const
{
return m_Node;
}
void IcingaApplication::SetService(string service)
{
m_Service = service;
}
string IcingaApplication::GetService(void) const
{
return m_Service;
}

View File

@ -12,6 +12,8 @@ private:
string m_PrivateKeyFile;
string m_PublicKeyFile;
string m_CAKeyFile;
string m_Node;
string m_Service;
int NewComponentHandler(const EventArgs& ea);
int DeletedComponentHandler(const EventArgs& ea);
@ -45,6 +47,12 @@ public:
void SetCAKeyFile(string cakey);
string GetCAKeyFile(void) const;
void SetNode(string node);
string GetNode(void) const;
void SetService(string service);
string GetService(void) const;
};
}

View File

@ -1,3 +0,0 @@
#include "i2-icinga.h"
using namespace icinga;

View File

@ -1,27 +0,0 @@
#ifndef IDENTITYMESSAGE_H
#define IDENTITYMESSAGE_H
namespace icinga
{
class I2_ICINGA_API IdentityMessage : public Message
{
public:
IdentityMessage(void) : Message() { }
IdentityMessage(const Message& message) : Message(message) { }
inline bool GetIdentity(string *value) const
{
return GetPropertyString("identity", value);
}
inline void SetIdentity(const string& value)
{
SetPropertyString("identity", value);
}
};
}
#endif /* IDENTITYMESSAGE_H */

View File

@ -15,48 +15,6 @@ JsonRpcClient::Ptr JsonRpcEndpoint::GetClient(void)
return m_Client;
}
void JsonRpcEndpoint::AddAllowedMethodSinkPrefix(string method)
{
m_AllowedMethodSinkPrefixes.insert(method);
}
void JsonRpcEndpoint::RemoveAllowedMethodSinkPrefix(string method)
{
m_AllowedMethodSinkPrefixes.erase(method);
}
bool JsonRpcEndpoint::IsAllowedMethodSink(string method) const
{
set<string>::iterator i;
for (i = m_AllowedMethodSinkPrefixes.begin(); i != m_AllowedMethodSinkPrefixes.end(); i++) {
if (method.compare(0, method.length(), method) == 0)
return true;
}
return false;
}
void JsonRpcEndpoint::AddAllowedMethodSourcePrefix(string method)
{
m_AllowedMethodSourcePrefixes.insert(method);
}
void JsonRpcEndpoint::RemoveAllowedMethodSourcePrefix(string method)
{
m_AllowedMethodSourcePrefixes.erase(method);
}
bool JsonRpcEndpoint::IsAllowedMethodSource(string method) const
{
set<string>::iterator i;
for (i = m_AllowedMethodSourcePrefixes.begin(); i != m_AllowedMethodSourcePrefixes.end(); i++) {
if (method.compare(0, method.length(), method) == 0)
return true;
}
return false;
}
void JsonRpcEndpoint::Connect(string host, unsigned short port, shared_ptr<SSL_CTX> sslContext)
{
m_PeerHostname = host;
@ -115,7 +73,7 @@ int JsonRpcEndpoint::NewMessageHandler(const NewMessageEventArgs& nmea)
string method;
if (message.GetPropertyString("method", &method)) {
if (!IsAllowedMethodSource(method))
if (!IsMethodSource(method))
return 0;
JsonRpcRequest request = message;

View File

@ -12,8 +12,6 @@ private:
JsonRpcClient::Ptr m_Client;
map<string, Endpoint::Ptr> m_PendingCalls;
Timer::Ptr m_ReconnectTimer;
set<string> m_AllowedMethodSinkPrefixes;
set<string> m_AllowedMethodSourcePrefixes;
string m_PeerHostname;
unsigned short m_PeerPort;
@ -37,13 +35,6 @@ public:
void SetAddress(string address);
virtual string GetAddress(void) const;
virtual void AddAllowedMethodSinkPrefix(string method);
virtual void RemoveAllowedMethodSinkPrefix(string method);
virtual bool IsAllowedMethodSink(string method) const;
virtual void AddAllowedMethodSourcePrefix(string method);
virtual void RemoveAllowedMethodSourcePrefix(string method);
virtual bool IsAllowedMethodSource(string method) const;
virtual bool IsLocal(void) const;
virtual bool IsConnected(void) const;

View File

@ -1,117 +0,0 @@
#include "i2-icinga.h"
using namespace icinga;
string SubscriptionComponent::GetName(void) const
{
return "subscriptioncomponent";
}
void SubscriptionComponent::Start(void)
{
m_SubscriptionEndpoint = make_shared<VirtualEndpoint>();
m_SubscriptionEndpoint->RegisterMethodHandler("message::Subscribe", bind_weak(&SubscriptionComponent::SubscribeMessageHandler, shared_from_this()));
m_SubscriptionEndpoint->RegisterMethodHandler("message::Provide", bind_weak(&SubscriptionComponent::ProvideMessageHandler, shared_from_this()));
m_SubscriptionEndpoint->RegisterMethodSource("message::Welcome");
m_SubscriptionEndpoint->RegisterMethodSource("message::Subscribe");
m_SubscriptionEndpoint->RegisterMethodSource("message::Provide");
EndpointManager::Ptr mgr = GetEndpointManager();
mgr->OnNewEndpoint += bind_weak(&SubscriptionComponent::NewEndpointHandler, shared_from_this());
mgr->ForeachEndpoint(bind(&SubscriptionComponent::NewEndpointHandler, this, _1));
mgr->RegisterEndpoint(m_SubscriptionEndpoint);
}
void SubscriptionComponent::Stop(void)
{
EndpointManager::Ptr mgr = GetEndpointManager();
if (mgr)
mgr->UnregisterEndpoint(m_SubscriptionEndpoint);
}
int SubscriptionComponent::SyncSubscription(Endpoint::Ptr target, string type, const NewMethodEventArgs& nmea)
{
JsonRpcRequest request;
request.SetVersion("2.0");
request.SetMethod(type);
SubscriptionMessage subscriptionMessage;
subscriptionMessage.SetMethod(nmea.Method);
request.SetParams(subscriptionMessage);
GetEndpointManager()->SendUnicastRequest(m_SubscriptionEndpoint, target, request);
return 0;
}
int SubscriptionComponent::SyncSubscriptions(Endpoint::Ptr target, const NewEndpointEventArgs& neea)
{
Endpoint::Ptr source = neea.Endpoint;
if (!source->IsLocal())
return 0;
source->ForeachMethodSink(bind(&SubscriptionComponent::SyncSubscription, this, target, "message::Subscribe", _1));
source->ForeachMethodSource(bind(&SubscriptionComponent::SyncSubscription, this, target, "message::Provide", _1));
// TODO: bind to endpoint's events
//endpoint->OnNewMethodSink...
return 0;
}
int SubscriptionComponent::NewEndpointHandler(const NewEndpointEventArgs& neea)
{
if (neea.Endpoint->IsLocal())
return 0;
neea.Endpoint->AddAllowedMethodSinkPrefix("message::");
neea.Endpoint->AddAllowedMethodSourcePrefix("message::");
/* we just assume the peer wants those messages */
neea.Endpoint->RegisterMethodSink("message::Welcome");
neea.Endpoint->RegisterMethodSink("message::Subscribe");
neea.Endpoint->RegisterMethodSink("message::Provide");
GetEndpointManager()->ForeachEndpoint(bind(&SubscriptionComponent::SyncSubscriptions, this, neea.Endpoint, _1));
/* signal the peer that we're done syncing subscriptions and are now
* ready to accept messages. */
JsonRpcRequest request;
request.SetMethod("message::Welcome");
GetEndpointManager()->SendUnicastRequest(m_SubscriptionEndpoint, neea.Endpoint, request);
return 0;
}
int SubscriptionComponent::SubscribeMessageHandler(const NewRequestEventArgs& nrea)
{
Message params;
if (!nrea.Request.GetParams(&params))
return 0;
SubscriptionMessage subscriptionMessage = params;
string method;
if (!subscriptionMessage.GetMethod(&method))
return 0;
nrea.Sender->RegisterMethodSink(method);
return 0;
}
int SubscriptionComponent::ProvideMessageHandler(const NewRequestEventArgs& nrea)
{
Message params;
if (!nrea.Request.GetParams(&params))
return 0;
SubscriptionMessage subscriptionMessage = params;
string method;
if (!subscriptionMessage.GetMethod(&method))
return 0;
nrea.Sender->RegisterMethodSource(method);
return 0;
}

View File

@ -1,28 +0,0 @@
#ifndef I2_SUBSCRIPTIONCOMPONENT_H
#define I2_SUBSCRIPTIONCOMPONENT_H
namespace icinga
{
class SubscriptionComponent : public IcingaComponent
{
private:
VirtualEndpoint::Ptr m_SubscriptionEndpoint;
int NewEndpointHandler(const NewEndpointEventArgs& neea);
int SubscribeMessageHandler(const NewRequestEventArgs& nrea);
int ProvideMessageHandler(const NewRequestEventArgs& nrea);
int IdentityMessageHandler(const NewRequestEventArgs& nrea);
int SyncSubscription(Endpoint::Ptr target, string type, const NewMethodEventArgs& nmea);
int SyncSubscriptions(Endpoint::Ptr target, const NewEndpointEventArgs& neea);
public:
virtual string GetName(void) const;
virtual void Start(void);
virtual void Stop(void);
};
}
#endif /* I2_SUBSCRIPTIONCOMPONENT_H */

View File

@ -1,3 +0,0 @@
#include "i2-icinga.h"
using namespace icinga;

View File

@ -1,27 +0,0 @@
#ifndef SUBSCRIPTIONMESSAGE_H
#define SUBSCRIPTIONMESSAGE_H
namespace icinga
{
class I2_ICINGA_API SubscriptionMessage : public Message
{
public:
SubscriptionMessage(void) : Message() { }
SubscriptionMessage(const Message& message) : Message(message) { }
inline bool GetMethod(string *value) const
{
return GetPropertyString("method", value);
}
inline void SetMethod(const string& value)
{
SetPropertyString("method", value);
}
};
}
#endif /* SUBSCRIPTIONMESSAGE_H */

View File

@ -59,36 +59,6 @@ void VirtualEndpoint::ProcessResponse(Endpoint::Ptr sender, const JsonRpcRespons
throw NotImplementedException();
}
void VirtualEndpoint::AddAllowedMethodSinkPrefix(string method)
{
/* Nothing to do here. */
}
void VirtualEndpoint::RemoveAllowedMethodSinkPrefix(string method)
{
/* Nothing to do here. */
}
void VirtualEndpoint::AddAllowedMethodSourcePrefix(string method)
{
/* Nothing to do here. */
}
void VirtualEndpoint::RemoveAllowedMethodSourcePrefix(string method)
{
/* Nothing to do here. */
}
bool VirtualEndpoint::IsAllowedMethodSink(string method) const
{
return true;
}
bool VirtualEndpoint::IsAllowedMethodSource(string method) const
{
return true;
}
void VirtualEndpoint::Stop(void)
{
/* Nothing to do here. */

View File

@ -25,13 +25,6 @@ public:
void RegisterMethodHandler(string method, function<int (const NewRequestEventArgs&)> callback);
void UnregisterMethodHandler(string method, function<int (const NewRequestEventArgs&)> callback);
virtual void AddAllowedMethodSinkPrefix(string method);
virtual void RemoveAllowedMethodSinkPrefix(string method);
virtual bool IsAllowedMethodSink(string method) const;
virtual void AddAllowedMethodSourcePrefix(string method);
virtual void RemoveAllowedMethodSourcePrefix(string method);
virtual bool IsAllowedMethodSource(string method) const;
virtual string GetAddress(void) const;
virtual bool IsLocal(void) const;

View File

@ -56,3 +56,18 @@ void Message::SetPropertyMessage(string key, const Message& value)
{
GetDictionary()->SetProperty(key, Variant(value.GetDictionary()));
}
void Message::AddUnnamedPropertyString(const string& value)
{
GetDictionary()->AddUnnamedPropertyString(value);
}
void Message::AddUnnamedPropertyInteger(long value)
{
GetDictionary()->AddUnnamedPropertyInteger(value);
}
void Message::AddUnnamedPropertyMessage(const Message& value)
{
GetDictionary()->AddUnnamedPropertyDictionary(value.GetDictionary());
}

View File

@ -24,6 +24,10 @@ public:
bool GetPropertyMessage(string key, Message *value) const;
void SetPropertyMessage(string key, const Message& value);
void AddUnnamedPropertyString(const string& value);
void AddUnnamedPropertyInteger(long value);
void AddUnnamedPropertyMessage(const Message& value);
};
}