Implemented support for replicating object tags [WIP - broken].

This commit is contained in:
Gunnar Beutner 2012-08-02 09:38:08 +02:00 committed by Gunnar Beutner
parent 7a9dcaacbe
commit a38379c56d
102 changed files with 1738 additions and 1297 deletions

View File

@ -30,6 +30,8 @@ libbase_la_SOURCES = \
object.h \ object.h \
process.cpp \ process.cpp \
process.h \ process.h \
qstring.cpp \
qstring.h \
ringbuffer.cpp \ ringbuffer.cpp \
ringbuffer.h \ ringbuffer.h \
scriptfunction.cpp \ scriptfunction.cpp \
@ -58,8 +60,8 @@ libbase_la_SOURCES = \
unix.h \ unix.h \
utility.cpp \ utility.cpp \
utility.h \ utility.h \
variant.cpp \ value.cpp \
variant.h \ value.h \
win32.cpp \ win32.cpp \
win32.h win32.h

View File

@ -91,6 +91,9 @@ void Application::RunEventLoop(void)
break; break;
Event::ProcessEvents(boost::get_system_time() + boost::posix_time::milliseconds(sleep * 1000)); Event::ProcessEvents(boost::get_system_time() + boost::posix_time::milliseconds(sleep * 1000));
DynamicObject::FinishTx();
DynamicObject::BeginTx();
} }
} }
@ -108,39 +111,47 @@ void Application::Shutdown(void)
* *
* @returns The path. * @returns The path.
*/ */
string Application::GetExePath(void) const String Application::GetExePath(void) const
{ {
static string result; static String result;
if (!result.empty()) if (!result.IsEmpty())
return result; return result;
string executablePath; String executablePath;
#ifndef _WIN32 #ifndef _WIN32
string argv0 = m_Arguments[0]; String argv0 = m_Arguments[0];
char buffer[MAXPATHLEN]; char buffer[MAXPATHLEN];
if (getcwd(buffer, sizeof(buffer)) == NULL) if (getcwd(buffer, sizeof(buffer)) == NULL)
throw_exception(PosixException("getcwd failed", errno)); throw_exception(PosixException("getcwd failed", errno));
string workingDirectory = buffer; String workingDirectory = buffer;
if (argv0[0] != '/') if (argv0[0] != '/')
executablePath = workingDirectory + "/" + argv0; executablePath = workingDirectory + "/" + argv0;
else else
executablePath = argv0; executablePath = argv0;
if (argv0.find_first_of('/') == string::npos) { bool foundSlash = false;
for (int i = 0; i < argv0.GetLength(); i++) {
if (argv0[i] == '/') {
foundSlash = true;
break;
}
}
if (!foundSlash) {
const char *pathEnv = getenv("PATH"); const char *pathEnv = getenv("PATH");
if (pathEnv != NULL) { if (pathEnv != NULL) {
vector<string> paths; vector<String> paths;
boost::algorithm::split(paths, pathEnv, boost::is_any_of(":")); boost::algorithm::split(paths, pathEnv, boost::is_any_of(":"));
bool foundPath = false; bool foundPath = false;
BOOST_FOREACH(string& path, paths) { BOOST_FOREACH(String& path, paths) {
string pathTest = path + "/" + argv0; String pathTest = path + "/" + argv0;
if (access(pathTest.c_str(), X_OK) == 0) { if (access(pathTest.CStr(), X_OK) == 0) {
executablePath = pathTest; executablePath = pathTest;
foundPath = true; foundPath = true;
break; break;
@ -148,13 +159,13 @@ string Application::GetExePath(void) const
} }
if (!foundPath) { if (!foundPath) {
executablePath.clear(); executablePath.Clear();
throw_exception(runtime_error("Could not determine executable path.")); throw_exception(runtime_error("Could not determine executable path."));
} }
} }
} }
if (realpath(executablePath.c_str(), buffer) == NULL) if (realpath(executablePath.CStr(), buffer) == NULL)
throw_exception(PosixException("realpath failed", errno)); throw_exception(PosixException("realpath failed", errno));
result = buffer; result = buffer;
@ -258,7 +269,9 @@ int Application::Run(int argc, char **argv)
m_Arguments.clear(); m_Arguments.clear();
for (int i = 0; i < argc; i++) for (int i = 0; i < argc; i++)
m_Arguments.push_back(string(argv[i])); m_Arguments.push_back(String(argv[i]));
DynamicObject::BeginTx();
if (IsDebugging()) { if (IsDebugging()) {
result = Main(m_Arguments); result = Main(m_Arguments);
@ -272,22 +285,24 @@ int Application::Run(int argc, char **argv)
Logger::Write(LogCritical, "base", "---"); Logger::Write(LogCritical, "base", "---");
Logger::Write(LogCritical, "base", "Exception: " + Utility::GetTypeName(typeid(ex))); Logger::Write(LogCritical, "base", "Exception: " + Utility::GetTypeName(typeid(ex)));
Logger::Write(LogCritical, "base", "Message: " + string(ex.what())); Logger::Write(LogCritical, "base", "Message: " + String(ex.what()));
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} }
DynamicObject::FinishTx();
return result; return result;
} }
void Application::UpdatePidFile(const string& filename) void Application::UpdatePidFile(const String& filename)
{ {
ClosePidFile(); ClosePidFile();
/* There's just no sane way of getting a file descriptor for a /* There's just no sane way of getting a file descriptor for a
* C++ ofstream which is why we're using FILEs here. */ * C++ ofstream which is why we're using FILEs here. */
m_PidFile = fopen(filename.c_str(), "w"); m_PidFile = fopen(filename.CStr(), "w");
if (m_PidFile == NULL) if (m_PidFile == NULL)
throw_exception(runtime_error("Could not open PID file '" + filename + "'")); throw_exception(runtime_error("Could not open PID file '" + filename + "'"));

View File

@ -41,7 +41,7 @@ public:
int Run(int argc, char **argv); int Run(int argc, char **argv);
virtual int Main(const vector<string>& args) = 0; virtual int Main(const vector<String>& args) = 0;
static void Shutdown(void); static void Shutdown(void);
@ -49,19 +49,19 @@ public:
static bool IsMainThread(void); static bool IsMainThread(void);
void UpdatePidFile(const string& filename); void UpdatePidFile(const String& filename);
void ClosePidFile(void); void ClosePidFile(void);
protected: protected:
void RunEventLoop(void); void RunEventLoop(void);
string GetExePath(void) const; String GetExePath(void) const;
private: private:
static Application::Ptr m_Instance; /**< The application instance. */ static Application::Ptr m_Instance; /**< The application instance. */
static bool m_ShuttingDown; /**< Whether the application is in the process of static bool m_ShuttingDown; /**< Whether the application is in the process of
shutting down. */ shutting down. */
vector<string> m_Arguments; /**< Command-line arguments */ vector<String> m_Arguments; /**< Command-line arguments */
FILE *m_PidFile; /**< The PID file */ FILE *m_PidFile; /**< The PID file */
static bool m_Debugging; /**< Whether debugging is enabled. */ static bool m_Debugging; /**< Whether debugging is enabled. */
static boost::thread::id m_MainThreadID; /**< ID of the main thread. */ static boost::thread::id m_MainThreadID; /**< ID of the main thread. */

View File

@ -26,6 +26,7 @@
<ClCompile Include="netstring.cpp" /> <ClCompile Include="netstring.cpp" />
<ClCompile Include="object.cpp" /> <ClCompile Include="object.cpp" />
<ClCompile Include="process.cpp" /> <ClCompile Include="process.cpp" />
<ClCompile Include="qstring.cpp" />
<ClCompile Include="ringbuffer.cpp" /> <ClCompile Include="ringbuffer.cpp" />
<ClCompile Include="scriptfunction.cpp" /> <ClCompile Include="scriptfunction.cpp" />
<ClCompile Include="scripttask.cpp" /> <ClCompile Include="scripttask.cpp" />
@ -40,7 +41,7 @@
<ClCompile Include="tlsclient.cpp" /> <ClCompile Include="tlsclient.cpp" />
<ClCompile Include="unix.cpp" /> <ClCompile Include="unix.cpp" />
<ClCompile Include="utility.cpp" /> <ClCompile Include="utility.cpp" />
<ClCompile Include="variant.cpp" /> <ClCompile Include="value.cpp" />
<ClCompile Include="win32.cpp" /> <ClCompile Include="win32.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -53,6 +54,7 @@
<ClInclude Include="fifo.h" /> <ClInclude Include="fifo.h" />
<ClInclude Include="ioqueue.h" /> <ClInclude Include="ioqueue.h" />
<ClInclude Include="netstring.h" /> <ClInclude Include="netstring.h" />
<ClInclude Include="qstring.h" />
<ClInclude Include="scriptfunction.h" /> <ClInclude Include="scriptfunction.h" />
<ClInclude Include="scripttask.h" /> <ClInclude Include="scripttask.h" />
<ClInclude Include="logger.h" /> <ClInclude Include="logger.h" />
@ -72,7 +74,7 @@
<ClInclude Include="tlsclient.h" /> <ClInclude Include="tlsclient.h" />
<ClInclude Include="unix.h" /> <ClInclude Include="unix.h" />
<ClInclude Include="utility.h" /> <ClInclude Include="utility.h" />
<ClInclude Include="variant.h" /> <ClInclude Include="value.h" />
<ClInclude Include="win32.h" /> <ClInclude Include="win32.h" />
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">

View File

@ -49,9 +49,6 @@
<ClCompile Include="utility.cpp"> <ClCompile Include="utility.cpp">
<Filter>Quelldateien</Filter> <Filter>Quelldateien</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="variant.cpp">
<Filter>Quelldateien</Filter>
</ClCompile>
<ClCompile Include="win32.cpp"> <ClCompile Include="win32.cpp">
<Filter>Quelldateien</Filter> <Filter>Quelldateien</Filter>
</ClCompile> </ClCompile>
@ -85,6 +82,12 @@
<ClCompile Include="dynamicobject.cpp"> <ClCompile Include="dynamicobject.cpp">
<Filter>Quelldateien</Filter> <Filter>Quelldateien</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="value.cpp">
<Filter>Quelldateien</Filter>
</ClCompile>
<ClCompile Include="qstring.cpp">
<Filter>Quelldateien</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="application.h"> <ClInclude Include="application.h">
@ -141,9 +144,6 @@
<ClInclude Include="utility.h"> <ClInclude Include="utility.h">
<Filter>Headerdateien</Filter> <Filter>Headerdateien</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="variant.h">
<Filter>Headerdateien</Filter>
</ClInclude>
<ClInclude Include="logger.h"> <ClInclude Include="logger.h">
<Filter>Headerdateien</Filter> <Filter>Headerdateien</Filter>
</ClInclude> </ClInclude>
@ -177,6 +177,12 @@
<ClInclude Include="dynamicobject.h"> <ClInclude Include="dynamicobject.h">
<Filter>Headerdateien</Filter> <Filter>Headerdateien</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="value.h">
<Filter>Headerdateien</Filter>
</ClInclude>
<ClInclude Include="qstring.h">
<Filter>Headerdateien</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Filter Include="Quelldateien"> <Filter Include="Quelldateien">

View File

@ -34,7 +34,7 @@ Component::Component(const Dictionary::Ptr& properties)
if (!IsLocal()) if (!IsLocal())
throw_exception(runtime_error("Component objects must be local.")); throw_exception(runtime_error("Component objects must be local."));
string path; String path;
#ifdef _WIN32 #ifdef _WIN32
path = GetName() + ".dll"; path = GetName() + ".dll";
#else /* _WIN32 */ #else /* _WIN32 */
@ -44,12 +44,12 @@ Component::Component(const Dictionary::Ptr& properties)
Logger::Write(LogInformation, "base", "Loading component '" + GetName() + "' (using library '" + path + "')"); Logger::Write(LogInformation, "base", "Loading component '" + GetName() + "' (using library '" + path + "')");
#ifdef _WIN32 #ifdef _WIN32
HMODULE hModule = LoadLibrary(path.c_str()); HMODULE hModule = LoadLibrary(path.CStr());
if (hModule == NULL) if (hModule == NULL)
throw_exception(Win32Exception("LoadLibrary('" + path + "') failed", GetLastError())); throw_exception(Win32Exception("LoadLibrary('" + path + "') failed", GetLastError()));
#else /* _WIN32 */ #else /* _WIN32 */
lt_dlhandle hModule = lt_dlopen(path.c_str()); lt_dlhandle hModule = lt_dlopen(path.CStr());
if (hModule == NULL) { if (hModule == NULL) {
throw_exception(runtime_error("Could not load module '" + path + "': " + lt_dlerror())); throw_exception(runtime_error("Could not load module '" + path + "': " + lt_dlerror()));
@ -92,29 +92,14 @@ Component::Component(const Dictionary::Ptr& properties)
} }
impl->m_Config = this; impl->m_Config = this;
SetImplementation(impl);
impl->Start(); impl->Start();
m_Impl = impl;
} }
Component::~Component(void) Component::~Component(void)
{ {
IComponent::Ptr impl = GetImplementation(); if (m_Impl)
m_Impl->Stop();
if (impl)
impl->Stop();
}
IComponent::Ptr Component::GetImplementation(void) const
{
IComponent::Ptr impl;
GetTag("impl", &impl);
return impl;
}
void Component::SetImplementation(const IComponent::Ptr& impl)
{
SetTag("impl", impl);
} }
/** /**
@ -122,12 +107,12 @@ void Component::SetImplementation(const IComponent::Ptr& impl)
* *
* @param componentDirectory The directory. * @param componentDirectory The directory.
*/ */
void Component::AddSearchDir(const string& componentDirectory) void Component::AddSearchDir(const String& componentDirectory)
{ {
#ifdef _WIN32 #ifdef _WIN32
SetDllDirectory(componentDirectory.c_str()); SetDllDirectory(componentDirectory.CStr());
#else /* _WIN32 */ #else /* _WIN32 */
lt_dladdsearchdir(componentDirectory.c_str()); lt_dladdsearchdir(componentDirectory.CStr());
#endif /* _WIN32 */ #endif /* _WIN32 */
} }

View File

@ -56,11 +56,10 @@ public:
Component(const Dictionary::Ptr& properties); Component(const Dictionary::Ptr& properties);
~Component(void); ~Component(void);
static void AddSearchDir(const string& componentDirectory); static void AddSearchDir(const String& componentDirectory);
private: private:
IComponent::Ptr GetImplementation(void) const; IComponent::Ptr m_Impl;
void SetImplementation(const IComponent::Ptr& impl);
}; };
typedef IComponent *(*CreateComponentFunction)(void); typedef IComponent *(*CreateComponentFunction)(void);

View File

@ -22,6 +22,68 @@
using namespace icinga; using namespace icinga;
/**
* Retrieves a value from the dictionary.
*
* @param key The key whose value should be retrieved.
* @returns The value or an empty value if the key was not found.
*/
Value Dictionary::Get(const String& key) const
{
map<String, Value>::const_iterator it;
it = m_Data.find(key);
if (it == m_Data.end())
return Value();
return it->second;
}
/**
* Sets a value in the dictionary.
*
* @param key The key.
* @param value The value.
*/
void Dictionary::Set(const String& key, const Value& value)
{
if (value.IsEmpty()) {
Remove(key);
return;
}
pair<map<String, Value>::iterator, bool> ret;
ret = m_Data.insert(make_pair(key, value));
if (!ret.second)
ret.first->second = value;
OnItemModified(key, value);
}
/**
* Adds an unnamed value to the dictionary.
*
* @param value The value.
* @returns The key that was used to add the new item.
*/
String Dictionary::Add(const Value& value)
{
Dictionary::Iterator it;
String key;
long index = GetLength();
do {
stringstream s;
s << "_" << index;
index++;
key = s.str();
it = m_Data.find(key);
} while (it != m_Data.end());
Set(key, value);
return key;
}
/** /**
* Returns an iterator to the beginning of the dictionary. * Returns an iterator to the beginning of the dictionary.
* *
@ -58,7 +120,7 @@ long Dictionary::GetLength(void) const
* @param key The key. * @param key The key.
* @returns true if the dictionary contains the key, false otherwise. * @returns true if the dictionary contains the key, false otherwise.
*/ */
bool Dictionary::Contains(const string& key) const bool Dictionary::Contains(const String& key) const
{ {
return (m_Data.find(key) != m_Data.end()); return (m_Data.find(key) != m_Data.end());
} }
@ -68,7 +130,7 @@ bool Dictionary::Contains(const string& key) const
* *
* @param key The key. * @param key The key.
*/ */
void Dictionary::Remove(const string& key) void Dictionary::Remove(const String& key)
{ {
Dictionary::Iterator it; Dictionary::Iterator it;
it = m_Data.find(key); it = m_Data.find(key);
@ -77,6 +139,21 @@ void Dictionary::Remove(const string& key)
return; return;
m_Data.erase(it); m_Data.erase(it);
OnItemModified(key, Value());
}
/**
* Removes the item specified by the iterator from the dictionary.
*
* @param it The iterator.
*/
void Dictionary::Remove(Dictionary::Iterator it)
{
String key = it->first;
m_Data.erase(it);
OnItemModified(key, Value());
} }
/** /**
@ -93,7 +170,7 @@ Dictionary::Ptr Dictionary::FromJson(cJSON *json)
throw_exception(invalid_argument("JSON type must be cJSON_Object.")); throw_exception(invalid_argument("JSON type must be cJSON_Object."));
for (cJSON *i = json->child; i != NULL; i = i->next) { for (cJSON *i = json->child; i != NULL; i = i->next) {
dictionary->Set(i->string, Variant::FromJson(i)); dictionary->Set(i->string, Value::FromJson(i));
} }
return dictionary; return dictionary;
@ -111,10 +188,10 @@ cJSON *Dictionary::ToJson(void) const
cJSON *json = cJSON_CreateObject(); cJSON *json = cJSON_CreateObject();
try { try {
string key; String key;
Variant value; Value value;
BOOST_FOREACH(tie(key, value), m_Data) { BOOST_FOREACH(tie(key, value), m_Data) {
cJSON_AddItemToObject(json, key.c_str(), value.ToJson()); cJSON_AddItemToObject(json, key.CStr(), value.ToJson());
} }
} catch (...) { } catch (...) {
cJSON_Delete(json); cJSON_Delete(json);
@ -123,3 +200,6 @@ cJSON *Dictionary::ToJson(void) const
return json; return json;
} }
void Dictionary::OnItemModified(const String& key, const Value& value)
{ }

View File

@ -34,82 +34,28 @@ public:
typedef shared_ptr<Dictionary> Ptr; typedef shared_ptr<Dictionary> Ptr;
typedef weak_ptr<Dictionary> WeakPtr; typedef weak_ptr<Dictionary> WeakPtr;
typedef map<string, Variant>::iterator Iterator; typedef map<String, Value>::iterator Iterator;
/** Value Get(const String& key) const;
* Retrieves a value from the dictionary. void Set(const String& key, const Value& value);
* String Add(const Value& value);
* @param key The key. bool Contains(const String& key) const;
* @param[out] value Pointer to the value.
* @returns true if the value was retrieved, false otherwise.
*/
template<typename T>
bool Get(const string& key, T *value) const
{
map<string, Variant>::const_iterator i = m_Data.find(key);
if (i == m_Data.end())
return false;
*value = static_cast<T>(i->second);
return true;
}
/**
* Sets a value in the dictionary.
*
* @param key The key.
* @param value The value.
*/
template<typename T>
void Set(const string& key, const T& value)
{
pair<typename map<string, Variant>::iterator, bool> ret;
ret = m_Data.insert(make_pair(key, value));
if (!ret.second)
ret.first->second = value;
}
/**
* Adds an unnamed value to the dictionary.
*
* @param value The value.
* @returns The key that was used to add the new item.
*/
template<typename T>
string Add(const T& value)
{
Iterator it;
string key;
long index = GetLength();
do {
stringstream s;
s << "_" << index;
index++;
key = s.str();
it = m_Data.find(key);
} while (it != m_Data.end());
Set(key, value);
return key;
}
bool Contains(const string& key) const;
Iterator Begin(void); Iterator Begin(void);
Iterator End(void); Iterator End(void);
long GetLength(void) const; long GetLength(void) const;
void Remove(const string& key); void Remove(const String& key);
void Remove(Iterator it);
static Dictionary::Ptr FromJson(cJSON *json); static Dictionary::Ptr FromJson(cJSON *json);
cJSON *ToJson(void) const; cJSON *ToJson(void) const;
virtual void OnItemModified(const String& key, const Value& value);
private: private:
map<string, Variant> m_Data; map<String, Value> m_Data;
}; };
inline Dictionary::Iterator range_begin(Dictionary::Ptr x) inline Dictionary::Iterator range_begin(Dictionary::Ptr x)

View File

@ -21,95 +21,267 @@
using namespace icinga; using namespace icinga;
map<pair<string, string>, Dictionary::Ptr> DynamicObject::m_PersistentTags; map<pair<String, String>, Dictionary::Ptr> DynamicObject::m_PersistentUpdates;
boost::signal<void (const DynamicObject::Ptr&)> DynamicObject::OnCommitted; double DynamicObject::m_CurrentTx = 0;
boost::signal<void (const DynamicObject::Ptr&)> DynamicObject::OnRemoved; set<DynamicObject::Ptr> DynamicObject::m_ModifiedObjects;
DynamicObject::DynamicObject(const Dictionary::Ptr& properties) boost::signal<void (const DynamicObject::Ptr&, const String& name)> DynamicObject::OnAttributeChanged;
: m_Properties(properties), m_Tags(boost::make_shared<Dictionary>()) boost::signal<void (const DynamicObject::Ptr&)> DynamicObject::OnRegistered;
boost::signal<void (const DynamicObject::Ptr&)> DynamicObject::OnUnregistered;
boost::signal<void (const set<DynamicObject::Ptr>&)> DynamicObject::OnTransactionClosing;
DynamicObject::DynamicObject(const Dictionary::Ptr& serializedObject)
: m_ConfigTx(0)
{ {
/* restore the object's tags */ RegisterAttribute("__name", Attribute_Config);
map<pair<string, string>, Dictionary::Ptr>::iterator it; RegisterAttribute("__type", Attribute_Config);
it = m_PersistentTags.find(make_pair(GetType(), GetName())); RegisterAttribute("__local", Attribute_Config);
if (it != m_PersistentTags.end()) { RegisterAttribute("__abstract", Attribute_Config);
m_Tags = it->second; RegisterAttribute("__source", Attribute_Local);
m_PersistentTags.erase(it); RegisterAttribute("methods", Attribute_Config);
/* apply state from the config item/remote update */
ApplyUpdate(serializedObject, true);
/* restore the object's persistent state */
map<pair<String, String>, Dictionary::Ptr>::iterator it;
it = m_PersistentUpdates.find(make_pair(GetType(), GetName()));
if (it != m_PersistentUpdates.end()) {
Logger::Write(LogDebug, "base", "Restoring persistent state "
"for object " + GetType() + ":" + GetName());
ApplyUpdate(it->second, true);
m_PersistentUpdates.erase(it);
} }
} }
void DynamicObject::SetProperties(const Dictionary::Ptr& properties) Dictionary::Ptr DynamicObject::BuildUpdate(double sinceTx, int attributeTypes) const
{ {
m_Properties = properties; DynamicObject::AttributeConstIterator it;
Dictionary::Ptr attrs = boost::make_shared<Dictionary>();
for (it = m_Attributes.begin(); it != m_Attributes.end(); it++) {
if (it->second.Type == Attribute_Transient)
continue;
if ((it->second.Type & attributeTypes) == 0)
continue;
if (it->second.Tx == 0)
continue;
if (it->second.Tx < sinceTx && !(it->second.Type == Attribute_Config && m_ConfigTx >= sinceTx))
continue;
Dictionary::Ptr attr = boost::make_shared<Dictionary>();
attr->Set("data", it->second.Data);
attr->Set("type", it->second.Type);
attr->Set("tx", it->second.Tx);
attrs->Set(it->first, attr);
}
Dictionary::Ptr update = boost::make_shared<Dictionary>();
update->Set("attrs", attrs);
if (m_ConfigTx >= sinceTx && attributeTypes & Attribute_Config)
update->Set("configTx", m_ConfigTx);
else if (attrs->GetLength() == 0)
return Dictionary::Ptr();
return update;
} }
Dictionary::Ptr DynamicObject::GetProperties(void) const void DynamicObject::ApplyUpdate(const Dictionary::Ptr& serializedUpdate, bool suppressEvents)
{ {
return m_Properties; double configTx = 0;
if (serializedUpdate->Contains("configTx")) {
configTx = serializedUpdate->Get("configTx");
if (configTx > m_ConfigTx)
ClearAttributesByType(Attribute_Config);
}
Dictionary::Ptr attrs = serializedUpdate->Get("attrs");
Dictionary::Iterator it;
for (it = attrs->Begin(); it != attrs->End(); it++) {
if (!it->second.IsObjectType<Dictionary>())
continue;
Dictionary::Ptr attr = it->second;
Value data = attr->Get("data");
int type = attr->Get("type");
double tx = attr->Get("tx");
if (type & Attribute_Config)
RegisterAttribute(it->first, Attribute_Config);
if (!HasAttribute(it->first))
RegisterAttribute(it->first, static_cast<DynamicAttributeType>(type));
InternalSetAttribute(it->first, data, tx, suppressEvents);
}
} }
void DynamicObject::SetTags(const Dictionary::Ptr& tags) void DynamicObject::SanitizeUpdate(const Dictionary::Ptr& serializedUpdate, int allowedTypes)
{ {
m_Tags = tags; if ((allowedTypes & Attribute_Config) == 0)
serializedUpdate->Remove("configTx");
Dictionary::Ptr attrs = serializedUpdate->Get("attrs");
Dictionary::Iterator prev, it;
for (it = attrs->Begin(); it != attrs->End(); ) {
if (!it->second.IsObjectType<Dictionary>())
continue;
Dictionary::Ptr attr = it->second;
int type = attr->Get("type");
if (type == 0 || type & ~allowedTypes) {
prev = it;
it++;
attrs->Remove(prev);
continue;
}
it++;
}
} }
Dictionary::Ptr DynamicObject::GetTags(void) const void DynamicObject::RegisterAttribute(const String& name, DynamicAttributeType type)
{ {
return m_Tags; DynamicAttribute attr;
attr.Type = type;
attr.Tx = 0;
pair<DynamicObject::AttributeIterator, bool> tt;
tt = m_Attributes.insert(make_pair(name, attr));
if (!tt.second)
tt.first->second.Type = type;
} }
string DynamicObject::GetType(void) const void DynamicObject::SetAttribute(const String& name, const Value& data)
{ {
string type; InternalSetAttribute(name, data, GetCurrentTx());
GetProperties()->Get("__type", &type); }
void DynamicObject::InternalSetAttribute(const String& name, const Value& data, double tx, bool suppressEvent)
{
DynamicAttribute attr;
attr.Type = Attribute_Transient;
attr.Data = data;
attr.Tx = tx;
pair<DynamicObject::AttributeIterator, bool> tt;
tt = m_Attributes.insert(make_pair(name, attr));
if (!tt.second && tx >= tt.first->second.Tx) {
tt.first->second.Data = data;
tt.first->second.Tx = tx;
}
if (tt.first->second.Type & Attribute_Config)
m_ConfigTx = tx;
if (!suppressEvent) {
m_ModifiedObjects.insert(GetSelf());
DynamicObject::OnAttributeChanged(GetSelf(), name);
}
}
Value DynamicObject::InternalGetAttribute(const String& name) const
{
DynamicObject::AttributeConstIterator it;
it = m_Attributes.find(name);
if (it == m_Attributes.end())
return Value();
else
return it->second.Data;
}
void DynamicObject::ClearAttribute(const String& name)
{
SetAttribute(name, Value());
}
bool DynamicObject::HasAttribute(const String& name) const
{
return (m_Attributes.find(name) != m_Attributes.end());
}
void DynamicObject::ClearAttributesByType(DynamicAttributeType type)
{
DynamicObject::AttributeIterator prev, at;
for (at = m_Attributes.begin(); at != m_Attributes.end(); ) {
if (at->second.Type == type) {
prev = at;
at++;
m_Attributes.erase(prev);
continue;
}
at++;
}
}
DynamicObject::AttributeConstIterator DynamicObject::AttributeBegin(void) const
{
return m_Attributes.begin();
}
DynamicObject::AttributeConstIterator DynamicObject::AttributeEnd(void) const
{
return m_Attributes.end();
}
String DynamicObject::GetType(void) const
{
String type;
GetAttribute("__type", &type);
return type; return type;
} }
string DynamicObject::GetName(void) const String DynamicObject::GetName(void) const
{ {
string name; String name;
GetProperties()->Get("__name", &name); GetAttribute("__name", &name);
return name; return name;
} }
bool DynamicObject::IsLocal(void) const bool DynamicObject::IsLocal(void) const
{ {
bool value = false; long local = 0;
GetProperties()->Get("__local", &value); GetAttribute("__local", &local);
return value; return (local != 0);
} }
bool DynamicObject::IsAbstract(void) const bool DynamicObject::IsAbstract(void) const
{ {
bool value = false; long abstract = 0;
GetProperties()->Get("__abstract", &value); GetAttribute("__abstract", &abstract);
return value; return (abstract != 0);
} }
void DynamicObject::SetSource(const string& value) void DynamicObject::SetSource(const String& value)
{ {
GetProperties()->Set("__source", value); SetAttribute("__source", value);
} }
string DynamicObject::GetSource(void) const String DynamicObject::GetSource(void) const
{ {
string value; String source;
GetProperties()->Get("__source", &value); GetAttribute("__source", &source);
return value; return source;
} }
void DynamicObject::SetCommitTimestamp(double ts) void DynamicObject::Register(void)
{
GetProperties()->Set("__tx", ts);
}
double DynamicObject::GetCommitTimestamp(void) const
{
double value = 0;
GetProperties()->Get("__tx", &value);
return value;
}
void DynamicObject::Commit(void)
{ {
assert(Application::IsMainThread()); assert(Application::IsMainThread());
@ -121,9 +293,7 @@ void DynamicObject::Commit(void)
ti = GetAllObjects().insert(make_pair(GetType(), DynamicObject::NameMap())); ti = GetAllObjects().insert(make_pair(GetType(), DynamicObject::NameMap()));
ti.first->second.insert(make_pair(GetName(), GetSelf())); ti.first->second.insert(make_pair(GetName(), GetSelf()));
SetCommitTimestamp(Utility::GetTime()); OnRegistered(GetSelf());
OnCommitted(GetSelf());
} }
void DynamicObject::Unregister(void) void DynamicObject::Unregister(void)
@ -143,10 +313,10 @@ void DynamicObject::Unregister(void)
tt->second.erase(nt); tt->second.erase(nt);
OnRemoved(GetSelf()); OnUnregistered(GetSelf());
} }
DynamicObject::Ptr DynamicObject::GetObject(const string& type, const string& name) DynamicObject::Ptr DynamicObject::GetObject(const String& type, const String& name)
{ {
DynamicObject::TypeMap::iterator tt; DynamicObject::TypeMap::iterator tt;
tt = GetAllObjects().find(type); tt = GetAllObjects().find(type);
@ -167,7 +337,7 @@ pair<DynamicObject::TypeMap::iterator, DynamicObject::TypeMap::iterator> Dynamic
return make_pair(GetAllObjects().begin(), GetAllObjects().end()); return make_pair(GetAllObjects().begin(), GetAllObjects().end());
} }
pair<DynamicObject::NameMap::iterator, DynamicObject::NameMap::iterator> DynamicObject::GetObjects(const string& type) pair<DynamicObject::NameMap::iterator, DynamicObject::NameMap::iterator> DynamicObject::GetObjects(const String& type)
{ {
pair<DynamicObject::TypeMap::iterator, bool> ti; pair<DynamicObject::TypeMap::iterator, bool> ti;
ti = GetAllObjects().insert(make_pair(type, DynamicObject::NameMap())); ti = GetAllObjects().insert(make_pair(type, DynamicObject::NameMap()));
@ -175,19 +345,15 @@ pair<DynamicObject::NameMap::iterator, DynamicObject::NameMap::iterator> Dynamic
return make_pair(ti.first->second.begin(), ti.first->second.end()); return make_pair(ti.first->second.begin(), ti.first->second.end());
} }
void DynamicObject::RemoveTag(const string& key) ScriptTask::Ptr DynamicObject::InvokeMethod(const String& method,
{ const vector<Value>& arguments, ScriptTask::CompletionCallback callback)
GetTags()->Remove(key);
}
ScriptTask::Ptr DynamicObject::InvokeMethod(const string& method,
const vector<Variant>& arguments, ScriptTask::CompletionCallback callback)
{ {
Dictionary::Ptr methods; Dictionary::Ptr methods;
string funcName; if (!GetAttribute("methods", &methods) || !methods->Contains(method))
if (!GetProperty("methods", &methods) || !methods->Get(method, &funcName))
return ScriptTask::Ptr(); return ScriptTask::Ptr();
String funcName = methods->Get(method);
ScriptFunction::Ptr func = ScriptFunction::GetByName(funcName); ScriptFunction::Ptr func = ScriptFunction::GetByName(funcName);
if (!func) if (!func)
@ -199,12 +365,12 @@ ScriptTask::Ptr DynamicObject::InvokeMethod(const string& method,
return task; return task;
} }
void DynamicObject::DumpObjects(const string& filename) void DynamicObject::DumpObjects(const String& filename)
{ {
Logger::Write(LogInformation, "base", "Dumping program state to file '" + filename + "'"); Logger::Write(LogInformation, "base", "Dumping program state to file '" + filename + "'");
ofstream fp; ofstream fp;
fp.open(filename.c_str()); fp.open(filename.CStr());
if (!fp) if (!fp)
throw_exception(runtime_error("Could not open '" + filename + "' file")); throw_exception(runtime_error("Could not open '" + filename + "' file"));
@ -222,18 +388,29 @@ void DynamicObject::DumpObjects(const string& filename)
persistentObject->Set("type", object->GetType()); persistentObject->Set("type", object->GetType());
persistentObject->Set("name", object->GetName()); persistentObject->Set("name", object->GetName());
int types = Attribute_Replicated;
/* only persist properties for replicated objects or for objects /* only persist properties for replicated objects or for objects
* that are marked as persistent */ * that are marked as persistent */
if (!object->GetSource().empty() /*|| object->IsPersistent()*/) if (!object->GetSource().IsEmpty() /*|| object->IsPersistent()*/) {
persistentObject->Set("properties", object->GetProperties()); types |= Attribute_Config;
persistentObject->Set("create", true);
} else {
persistentObject->Set("create", false);
}
persistentObject->Set("tags", object->GetTags()); Dictionary::Ptr update = object->BuildUpdate(0, types);
Variant value = persistentObject; if (!update)
string json = value.Serialize(); continue;
/* This is quite ugly, unfortunatelly Netstring requires an IOQueue object */ persistentObject->Set("update", update);
Netstring::WriteStringToIOQueue(fifo.get(), json);
Value value = persistentObject;
String json = value.Serialize();
/* This is quite ugly, unfortunatelly NetString requires an IOQueue object */
NetString::WriteStringToIOQueue(fifo.get(), json);
size_t count; size_t count;
while ((count = fifo->GetAvailableBytes()) > 0) { while ((count = fifo->GetAvailableBytes()) > 0) {
@ -249,12 +426,12 @@ void DynamicObject::DumpObjects(const string& filename)
} }
} }
void DynamicObject::RestoreObjects(const string& filename) void DynamicObject::RestoreObjects(const String& filename)
{ {
Logger::Write(LogInformation, "base", "Restoring program state from file '" + filename + "'"); Logger::Write(LogInformation, "base", "Restoring program state from file '" + filename + "'");
std::ifstream fp; std::ifstream fp;
fp.open(filename.c_str()); fp.open(filename.CStr());
/* TODO: Fix this horrible mess. */ /* TODO: Fix this horrible mess. */
FIFO::Ptr fifo = boost::make_shared<FIFO>(); FIFO::Ptr fifo = boost::make_shared<FIFO>();
@ -265,36 +442,27 @@ void DynamicObject::RestoreObjects(const string& filename)
fifo->Write(buffer, fp.gcount()); fifo->Write(buffer, fp.gcount());
} }
string message; String message;
while (Netstring::ReadStringFromIOQueue(fifo.get(), &message)) { while (NetString::ReadStringFromIOQueue(fifo.get(), &message)) {
Variant value = Variant::Deserialize(message); Value value = Value::Deserialize(message);
if (!value.IsObjectType<Dictionary>()) if (!value.IsObjectType<Dictionary>())
throw_exception(runtime_error("JSON objects in the program state file must be dictionaries.")); throw_exception(runtime_error("JSON objects in the program state file must be dictionaries."));
Dictionary::Ptr persistentObject = value; Dictionary::Ptr persistentObject = value;
string type; String type = persistentObject->Get("type");
if (!persistentObject->Get("type", &type)) String name = persistentObject->Get("name");
continue; int create = persistentObject->Get("create");
Dictionary::Ptr update = persistentObject->Get("update");
string name; if (create != 0) {
if (!persistentObject->Get("name", &name)) DynamicObject::Ptr object = Create(type, update);
continue; object->Register();
Dictionary::Ptr tags;
if (!persistentObject->Get("tags", &tags))
continue;
Dictionary::Ptr properties;
if (persistentObject->Get("properties", &properties)) {
DynamicObject::Ptr object = Create(type, properties);
object->SetTags(tags);
object->Commit();
} else { } else {
/* keep non-replicated objects until another config object with /* keep non-replicated objects until another config object with
* the same name is created (which is when we restore its tags) */ * the same name is created (which is when we restore its tags) */
m_PersistentTags[make_pair(type, name)] = tags; m_PersistentUpdates[make_pair(type, name)] = update;
} }
} }
} }
@ -311,7 +479,7 @@ DynamicObject::ClassMap& DynamicObject::GetClasses(void)
return classes; return classes;
} }
void DynamicObject::RegisterClass(const string& type, DynamicObject::Factory factory) void DynamicObject::RegisterClass(const String& type, DynamicObject::Factory factory)
{ {
if (GetObjects(type).first != GetObjects(type).second) if (GetObjects(type).first != GetObjects(type).second)
throw_exception(runtime_error("Cannot register class for type '" + throw_exception(runtime_error("Cannot register class for type '" +
@ -320,7 +488,7 @@ void DynamicObject::RegisterClass(const string& type, DynamicObject::Factory fac
GetClasses()[type] = factory; GetClasses()[type] = factory;
} }
DynamicObject::Ptr DynamicObject::Create(const string& type, const Dictionary::Ptr& properties) DynamicObject::Ptr DynamicObject::Create(const String& type, const Dictionary::Ptr& properties)
{ {
DynamicObject::ClassMap::iterator it; DynamicObject::ClassMap::iterator it;
it = GetClasses().find(type); it = GetClasses().find(type);
@ -330,3 +498,23 @@ DynamicObject::Ptr DynamicObject::Create(const string& type, const Dictionary::P
else else
return boost::make_shared<DynamicObject>(properties); return boost::make_shared<DynamicObject>(properties);
} }
double DynamicObject::GetCurrentTx(void)
{
assert(m_CurrentTx != 0);
return m_CurrentTx;
}
void DynamicObject::BeginTx(void)
{
m_CurrentTx = Utility::GetTime();
}
void DynamicObject::FinishTx(void)
{
OnTransactionClosing(m_ModifiedObjects);
m_ModifiedObjects.clear();
m_CurrentTx = 0;
}

View File

@ -23,6 +23,30 @@
namespace icinga namespace icinga
{ {
enum DynamicAttributeType
{
Attribute_Transient = 1,
/* Unlike transient attributes local attributes are persisted
* in the program state file. */
Attribute_Local = 2,
/* Replicated attributes are sent to other daemons for which
* replication is enabled. */
Attribute_Replicated = 4,
/* Attributes read from the config file are implicitly marked
* as config attributes. */
Attribute_Config = 8,
};
struct DynamicAttribute
{
Value Data;
DynamicAttributeType Type;
double Tx;
};
/** /**
* A dynamic object that can be instantiated from the configuration file. * A dynamic object that can be instantiated from the configuration file.
* *
@ -36,84 +60,102 @@ public:
typedef function<DynamicObject::Ptr (const Dictionary::Ptr&)> Factory; typedef function<DynamicObject::Ptr (const Dictionary::Ptr&)> Factory;
typedef map<string, Factory> ClassMap; typedef map<String, Factory> ClassMap;
typedef map<string, DynamicObject::Ptr> NameMap; typedef map<String, DynamicObject::Ptr> NameMap;
typedef map<string, NameMap> TypeMap; typedef map<String, NameMap> TypeMap;
DynamicObject(const Dictionary::Ptr& properties); typedef map<String, DynamicAttribute> AttributeMap;
typedef AttributeMap::iterator AttributeIterator;
typedef AttributeMap::const_iterator AttributeConstIterator;
void SetProperties(const Dictionary::Ptr& config); DynamicObject(const Dictionary::Ptr& serializedObject);
Dictionary::Ptr GetProperties(void) const;
Dictionary::Ptr BuildUpdate(double sinceTx, int attributeTypes) const;
void ApplyUpdate(const Dictionary::Ptr& serializedUpdate, bool suppressEvents = false);
static void SanitizeUpdate(const Dictionary::Ptr& serializedUpdate, int allowedTypes);
void RegisterAttribute(const String& name, DynamicAttributeType type);
void SetAttribute(const String& name, const Value& data);
template<typename T> template<typename T>
bool GetProperty(const string& key, T *value) const bool GetAttribute(const String& name, T *retval) const
{ {
return GetProperties()->Get(key, value); Value data = InternalGetAttribute(name);
if (data.IsEmpty())
return false;
*retval = static_cast<T>(data);
return true;
} }
void SetTags(const Dictionary::Ptr& tags); void ClearAttribute(const String& name);
Dictionary::Ptr GetTags(void) const;
template<typename T> bool HasAttribute(const String& name) const;
void SetTag(const string& key, const T& value)
{
GetTags()->Set(key, value);
}
template<typename T> void ClearAttributesByType(DynamicAttributeType type);
bool GetTag(const string& key, T *value) const
{
return GetTags()->Get(key, value);
}
void RemoveTag(const string& key); AttributeConstIterator AttributeBegin(void) const;
AttributeConstIterator AttributeEnd(void) const;
ScriptTask::Ptr InvokeMethod(const string& method, static boost::signal<void (const DynamicObject::Ptr&, const String& name)> OnAttributeChanged;
const vector<Variant>& arguments, ScriptTask::CompletionCallback callback); static boost::signal<void (const DynamicObject::Ptr&)> OnRegistered;
static boost::signal<void (const DynamicObject::Ptr&)> OnUnregistered;
static boost::signal<void (const set<DynamicObject::Ptr>&)> OnTransactionClosing;
string GetType(void) const; ScriptTask::Ptr InvokeMethod(const String& method,
string GetName(void) const; const vector<Value>& arguments, ScriptTask::CompletionCallback callback);
String GetType(void) const;
String GetName(void) const;
bool IsLocal(void) const; bool IsLocal(void) const;
bool IsAbstract(void) const; bool IsAbstract(void) const;
void SetSource(const string& value); void SetSource(const String& value);
string GetSource(void) const; String GetSource(void) const;
double GetCommitTimestamp(void) const; void SetTx(double tx);
double GetTx(void) const;
void Commit(void); void Register(void);
void Unregister(void); void Unregister(void);
static DynamicObject::Ptr GetObject(const string& type, const string& name); static DynamicObject::Ptr GetObject(const String& type, const String& name);
static pair<TypeMap::iterator, TypeMap::iterator> GetTypes(void); static pair<TypeMap::iterator, TypeMap::iterator> GetTypes(void);
static pair<NameMap::iterator, NameMap::iterator> GetObjects(const string& type); static pair<NameMap::iterator, NameMap::iterator> GetObjects(const String& type);
static void DumpObjects(const string& filename); static void DumpObjects(const String& filename);
static void RestoreObjects(const string& filename); static void RestoreObjects(const String& filename);
static void RegisterClass(const string& type, Factory factory); static void RegisterClass(const String& type, Factory factory);
static DynamicObject::Ptr Create(const string& type, const Dictionary::Ptr& properties); static DynamicObject::Ptr Create(const String& type, const Dictionary::Ptr& properties);
static boost::signal<void (const DynamicObject::Ptr&)> OnCommitted; static double GetCurrentTx(void);
static boost::signal<void (const DynamicObject::Ptr&)> OnRemoved; static void BeginTx(void);
static void FinishTx(void);
private: private:
void InternalSetAttribute(const String& name, const Value& data, double tx, bool suppressEvent = false);
Value InternalGetAttribute(const String& name) const;
static ClassMap& GetClasses(void); static ClassMap& GetClasses(void);
static TypeMap& GetAllObjects(void); static TypeMap& GetAllObjects(void);
Dictionary::Ptr m_Properties; AttributeMap m_Attributes;
Dictionary::Ptr m_Tags; double m_ConfigTx;
static map<pair<string, string>, Dictionary::Ptr> m_PersistentTags; static map<pair<String, String>, Dictionary::Ptr> m_PersistentUpdates;
static double m_CurrentTx;
void SetCommitTimestamp(double ts); static set<DynamicObject::Ptr> m_ModifiedObjects;
}; };
class RegisterClassHelper class RegisterClassHelper
{ {
public: public:
RegisterClassHelper(const string& name, DynamicObject::Factory factory) RegisterClassHelper(const String& name, DynamicObject::Factory factory)
{ {
DynamicObject::RegisterClass(name, factory); DynamicObject::RegisterClass(name, factory);
} }

View File

@ -46,7 +46,7 @@ void Exception::SetCode(int code)
* *
* @returns The description. * @returns The description.
*/ */
string Exception::GetMessage(void) const String Exception::GetMessage(void) const
{ {
return m_Message; return m_Message;
} }
@ -58,7 +58,7 @@ string Exception::GetMessage(void) const
*/ */
const char *Exception::what(void) const throw() const char *Exception::what(void) const throw()
{ {
return m_Message.c_str(); return m_Message.CStr();
} }
/** /**
@ -66,7 +66,7 @@ const char *Exception::what(void) const throw()
* *
* @param message The description. * @param message The description.
*/ */
void Exception::SetMessage(string message) void Exception::SetMessage(String message)
{ {
m_Message = message; m_Message = message;
} }
@ -76,19 +76,19 @@ void Exception::SetMessage(string message)
* Formats an Win32 error code. * Formats an Win32 error code.
* *
* @param code The error code. * @param code The error code.
* @returns A string describing the error. * @returns A String describing the error.
*/ */
string Win32Exception::FormatErrorCode(int code) String Win32Exception::FormatErrorCode(int code)
{ {
char *message; char *message;
string result = "Unknown error."; String result = "Unknown error.";
DWORD rc = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | DWORD rc = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM, NULL, code, 0, (char *)&message, FORMAT_MESSAGE_FROM_SYSTEM, NULL, code, 0, (char *)&message,
0, NULL); 0, NULL);
if (rc != 0) { if (rc != 0) {
result = string(message); result = String(message);
LocalFree(message); LocalFree(message);
/* remove trailing new-line characters */ /* remove trailing new-line characters */
@ -103,9 +103,9 @@ string Win32Exception::FormatErrorCode(int code)
* Formats a Posix error code. * Formats a Posix error code.
* *
* @param code The error code. * @param code The error code.
* @returns A string describing the error. * @returns A String describing the error.
*/ */
string PosixException::FormatErrorCode(int code) String PosixException::FormatErrorCode(int code)
{ {
return strerror(code); return strerror(code);
} }
@ -114,9 +114,9 @@ string PosixException::FormatErrorCode(int code)
* Formats an OpenSSL error code. * Formats an OpenSSL error code.
* *
* @param code The error code. * @param code The error code.
* @returns A string describing the error. * @returns A String describing the error.
*/ */
string OpenSSLException::FormatErrorCode(int code) String OpenSSLException::FormatErrorCode(int code)
{ {
const char *message = ERR_error_string(code, NULL); const char *message = ERR_error_string(code, NULL);

View File

@ -35,11 +35,11 @@ public:
: m_Message(), m_Code(0) : m_Message(), m_Code(0)
{ } { }
Exception(string message) Exception(String message)
: m_Message(message), m_Code(0) : m_Message(message), m_Code(0)
{ } { }
Exception(string message, int code) Exception(String message, int code)
: m_Message(message), m_Code(code) : m_Message(message), m_Code(code)
{ } { }
@ -50,16 +50,16 @@ public:
{ } { }
int GetCode(void) const; int GetCode(void) const;
string GetMessage(void) const; String GetMessage(void) const;
virtual const char *what(void) const throw(); virtual const char *what(void) const throw();
protected: protected:
void SetCode(int code); void SetCode(int code);
void SetMessage(string message); void SetMessage(String message);
private: private:
string m_Message; String m_Message;
int m_Code; int m_Code;
}; };
@ -70,7 +70,7 @@ private:
inline klass(void) : Exception() \ inline klass(void) : Exception() \
{ } \ { } \
\ \
inline klass(string message) \ inline klass(String message) \
: Exception(message) \ : Exception(message) \
{ } \ { } \
} }
@ -96,17 +96,17 @@ public:
* @param message An error message. * @param message An error message.
* @param errorCode A Win32 error code. * @param errorCode A Win32 error code.
*/ */
inline Win32Exception(const string& message, int errorCode) inline Win32Exception(const String& message, int errorCode)
: Exception(message + ": " + FormatErrorCode(errorCode), errorCode) : Exception(message + ": " + FormatErrorCode(errorCode), errorCode)
{ } { }
/** /**
* Returns a string that describes the Win32 error. * Returns a String that describes the Win32 error.
* *
* @param code The Win32 error code. * @param code The Win32 error code.
* @returns A description of the error. * @returns A description of the error.
*/ */
static string FormatErrorCode(int code); static String FormatErrorCode(int code);
}; };
#endif /* _WIN32 */ #endif /* _WIN32 */
@ -122,17 +122,17 @@ public:
* @param message An error message. * @param message An error message.
* @param errorCode A Posix (errno) error code. * @param errorCode A Posix (errno) error code.
*/ */
inline PosixException(const string& message, int errorCode) inline PosixException(const String& message, int errorCode)
: Exception(message + ": " + FormatErrorCode(errorCode), errorCode) : Exception(message + ": " + FormatErrorCode(errorCode), errorCode)
{ } { }
/** /**
* Returns a string that describes the Posix error. * Returns a String that describes the Posix error.
* *
* @param code The Posix error code. * @param code The Posix error code.
* @returns A description of the error. * @returns A description of the error.
*/ */
static string FormatErrorCode(int code); static String FormatErrorCode(int code);
}; };
/** /**
@ -147,17 +147,17 @@ public:
* @param message An error message. * @param message An error message.
* @param errorCode An OpenSSL error code. * @param errorCode An OpenSSL error code.
*/ */
inline OpenSSLException(const string& message, int errorCode) inline OpenSSLException(const String& message, int errorCode)
: Exception(message + ": " + FormatErrorCode(errorCode), errorCode) : Exception(message + ": " + FormatErrorCode(errorCode), errorCode)
{ } { }
/** /**
* Returns a string that describes the OpenSSL error. * Returns a String that describes the OpenSSL error.
* *
* @param code The OpenSSL error code. * @param code The OpenSSL error code.
* @returns A description of the error. * @returns A description of the error.
*/ */
static string FormatErrorCode(int code); static String FormatErrorCode(int code);
}; };
} }

View File

@ -90,7 +90,6 @@
#include <algorithm> #include <algorithm>
#include <deque> #include <deque>
using std::string;
using std::vector; using std::vector;
using std::map; using std::map;
using std::list; using std::list;
@ -98,6 +97,7 @@ using std::set;
using std::multimap; using std::multimap;
using std::pair; using std::pair;
using std::deque; using std::deque;
using std::make_pair;
using std::stringstream; using std::stringstream;
using std::istream; using std::istream;
@ -164,11 +164,12 @@ namespace tuples = boost::tuples;
# define I2_BASE_API I2_IMPORT # define I2_BASE_API I2_IMPORT
#endif /* I2_BASE_BUILD */ #endif /* I2_BASE_BUILD */
#include "qstring.h"
#include "utility.h" #include "utility.h"
#include "object.h" #include "object.h"
#include "exception.h" #include "exception.h"
#include "event.h" #include "event.h"
#include "variant.h" #include "value.h"
#include "dictionary.h" #include "dictionary.h"
#include "ringbuffer.h" #include "ringbuffer.h"
#include "timer.h" #include "timer.h"

View File

@ -32,11 +32,15 @@ REGISTER_CLASS(Logger);
Logger::Logger(const Dictionary::Ptr& properties) Logger::Logger(const Dictionary::Ptr& properties)
: DynamicObject(properties) : DynamicObject(properties)
{ {
RegisterAttribute("type", Attribute_Config);
RegisterAttribute("path", Attribute_Config);
RegisterAttribute("severity", Attribute_Config);
if (!IsLocal()) if (!IsLocal())
throw_exception(runtime_error("Logger objects must be local.")); throw_exception(runtime_error("Logger objects must be local."));
string type; String type;
if (!GetProperty("type", &type)) if (!GetAttribute("type", &type))
throw_exception(runtime_error("Logger objects must have a 'type' property.")); throw_exception(runtime_error("Logger objects must have a 'type' property."));
ILogger::Ptr impl; ILogger::Ptr impl;
@ -48,8 +52,8 @@ Logger::Logger(const Dictionary::Ptr& properties)
throw_exception(invalid_argument("Syslog is not supported on Windows.")); throw_exception(invalid_argument("Syslog is not supported on Windows."));
#endif /* _WIN32 */ #endif /* _WIN32 */
} else if (type == "file") { } else if (type == "file") {
string path; String path;
if (!GetProperty("path", &path)) if (!GetAttribute("path", &path))
throw_exception(invalid_argument("'log' object of type 'file' must have a 'path' property")); throw_exception(invalid_argument("'log' object of type 'file' must have a 'path' property"));
StreamLogger::Ptr slogger = boost::make_shared<StreamLogger>(); StreamLogger::Ptr slogger = boost::make_shared<StreamLogger>();
@ -63,7 +67,7 @@ Logger::Logger(const Dictionary::Ptr& properties)
} }
impl->m_Config = this; impl->m_Config = this;
SetImplementation(impl); m_Impl = impl;
} }
/** /**
@ -73,8 +77,8 @@ Logger::Logger(const Dictionary::Ptr& properties)
* @param facility The log facility. * @param facility The log facility.
* @param message The message. * @param message The message.
*/ */
void Logger::Write(LogSeverity severity, const string& facility, void Logger::Write(LogSeverity severity, const String& facility,
const string& message) const String& message)
{ {
LogEntry entry; LogEntry entry;
entry.Timestamp = Utility::GetTime(); entry.Timestamp = Utility::GetTime();
@ -92,12 +96,9 @@ void Logger::Write(LogSeverity severity, const string& facility,
*/ */
LogSeverity Logger::GetMinSeverity(void) const LogSeverity Logger::GetMinSeverity(void) const
{ {
string strSeverity; String strSeverity = "information";
LogSeverity severity = LogInformation; GetAttribute("severity", &strSeverity);
if (GetProperty("severity", &strSeverity)) return Logger::StringToSeverity(strSeverity);
severity = Logger::StringToSeverity(strSeverity);
return severity;
} }
/** /**
@ -112,23 +113,11 @@ void Logger::ForwardLogEntry(const LogEntry& entry)
Logger::Ptr logger = dynamic_pointer_cast<Logger>(object); Logger::Ptr logger = dynamic_pointer_cast<Logger>(object);
if (entry.Severity >= logger->GetMinSeverity()) if (entry.Severity >= logger->GetMinSeverity())
logger->GetImplementation()->ProcessLogEntry(entry); logger->m_Impl->ProcessLogEntry(entry);
} }
} }
ILogger::Ptr Logger::GetImplementation(void) const String Logger::SeverityToString(LogSeverity severity)
{
ILogger::Ptr impl;
GetTag("impl", &impl);
return impl;
}
void Logger::SetImplementation(const ILogger::Ptr& impl)
{
SetTag("impl", impl);
}
string Logger::SeverityToString(LogSeverity severity)
{ {
switch (severity) { switch (severity) {
case LogDebug: case LogDebug:
@ -144,7 +133,7 @@ string Logger::SeverityToString(LogSeverity severity)
} }
} }
LogSeverity Logger::StringToSeverity(const string& severity) LogSeverity Logger::StringToSeverity(const String& severity)
{ {
if (severity == "debug") if (severity == "debug")
return LogDebug; return LogDebug;

View File

@ -44,8 +44,8 @@ enum LogSeverity
struct LogEntry { struct LogEntry {
double Timestamp; double Timestamp;
LogSeverity Severity; LogSeverity Severity;
string Facility; String Facility;
string Message; String Message;
}; };
/** /**
@ -76,19 +76,17 @@ public:
Logger(const Dictionary::Ptr& properties); Logger(const Dictionary::Ptr& properties);
static void Write(LogSeverity severity, const string& facility, static void Write(LogSeverity severity, const String& facility,
const string& message); const String& message);
static string SeverityToString(LogSeverity severity); static String SeverityToString(LogSeverity severity);
static LogSeverity StringToSeverity(const string& severity); static LogSeverity StringToSeverity(const String& severity);
LogSeverity GetMinSeverity(void) const; LogSeverity GetMinSeverity(void) const;
private: private:
LogSeverity m_MinSeverity; LogSeverity m_MinSeverity;
ILogger::Ptr m_Impl;
ILogger::Ptr GetImplementation(void) const;
void SetImplementation(const ILogger::Ptr& impl);
static void ForwardLogEntry(const LogEntry& entry); static void ForwardLogEntry(const LogEntry& entry);
}; };

View File

@ -22,19 +22,19 @@
using namespace icinga; using namespace icinga;
/** /**
* Reads data from an IOQueue in netstring format. * Reads data from an IOQueue in netString format.
* *
* @param fifo The IOQueue to read from. * @param fifo The IOQueue to read from.
* @param[out] str The string that has been read from the FIFO. * @param[out] str The String that has been read from the FIFO.
* @returns true if a complete string was read from the FIFO, false otherwise. * @returns true if a complete String was read from the FIFO, false otherwise.
* @exception invalid_argument The input stream is invalid. * @exception invalid_argument The input stream is invalid.
* @see https://github.com/PeterScott/netstring-c/blob/master/netstring.c * @see https://github.com/PeterScott/netString-c/blob/master/netString.c
*/ */
bool Netstring::ReadStringFromIOQueue(IOQueue *queue, string *str) bool NetString::ReadStringFromIOQueue(IOQueue *queue, String *str)
{ {
size_t buffer_length = queue->GetAvailableBytes(); size_t buffer_length = queue->GetAvailableBytes();
/* minimum netstring length is 3 */ /* minimum netString length is 3 */
if (buffer_length < 3) if (buffer_length < 3)
return false; return false;
@ -52,7 +52,7 @@ bool Netstring::ReadStringFromIOQueue(IOQueue *queue, string *str)
/* no leading zeros allowed */ /* no leading zeros allowed */
if (buffer[0] == '0' && isdigit(buffer[1])) { if (buffer[0] == '0' && isdigit(buffer[1])) {
free(buffer); free(buffer);
throw_exception(invalid_argument("Invalid netstring (leading zero)")); throw_exception(invalid_argument("Invalid netString (leading zero)"));
} }
size_t len, i; size_t len, i;
@ -91,16 +91,16 @@ bool Netstring::ReadStringFromIOQueue(IOQueue *queue, string *str)
/* check for the colon delimiter */ /* check for the colon delimiter */
if (buffer[i] != ':') { if (buffer[i] != ':') {
free(buffer); free(buffer);
throw_exception(invalid_argument("Invalid Netstring (missing :)")); throw_exception(invalid_argument("Invalid NetString (missing :)"));
} }
/* check for the comma delimiter after the string */ /* check for the comma delimiter after the String */
if (buffer[i + 1 + len] != ',') { if (buffer[i + 1 + len] != ',') {
free(buffer); free(buffer);
throw_exception(invalid_argument("Invalid Netstring (missing ,)")); throw_exception(invalid_argument("Invalid NetString (missing ,)"));
} }
*str = string(&buffer[i + 1], &buffer[i + 1 + len]); *str = String(&buffer[i + 1], &buffer[i + 1 + len]);
free(buffer); free(buffer);
@ -111,18 +111,18 @@ bool Netstring::ReadStringFromIOQueue(IOQueue *queue, string *str)
} }
/** /**
* Writes data into a FIFO using the netstring format. * Writes data into a FIFO using the netString format.
* *
* @param fifo The FIFO. * @param fifo The FIFO.
* @param str The string that is to be written. * @param str The String that is to be written.
*/ */
void Netstring::WriteStringToIOQueue(IOQueue *queue, const string& str) void NetString::WriteStringToIOQueue(IOQueue *queue, const String& str)
{ {
stringstream prefixbuf; stringstream prefixbuf;
prefixbuf << str.size() << ":"; prefixbuf << str.GetLength() << ":";
string prefix = prefixbuf.str(); String prefix = prefixbuf.str();
queue->Write(prefix.c_str(), prefix.size()); queue->Write(prefix.CStr(), prefix.GetLength());
queue->Write(str.c_str(), str.size()); queue->Write(str.CStr(), str.GetLength());
queue->Write(",", 1); queue->Write(",", 1);
} }

View File

@ -24,20 +24,20 @@ namespace icinga
{ {
/** /**
* Helper functions for reading/writing messages in the netstring format. * Helper functions for reading/writing messages in the netString format.
* *
* @see http://cr.yp.to/proto/netstrings.txt * @see http://cr.yp.to/proto/netStrings.txt
* *
* @ingroup base * @ingroup base
*/ */
class I2_BASE_API Netstring class I2_BASE_API NetString
{ {
public: public:
static bool ReadStringFromIOQueue(IOQueue *queue, string *message); static bool ReadStringFromIOQueue(IOQueue *queue, String *message);
static void WriteStringToIOQueue(IOQueue *queue, const string& message); static void WriteStringToIOQueue(IOQueue *queue, const String& message);
private: private:
Netstring(void); NetString(void);
}; };
} }

View File

@ -30,7 +30,7 @@ boost::mutex Process::m_Mutex;
deque<Process::Ptr> Process::m_Tasks; deque<Process::Ptr> Process::m_Tasks;
condition_variable Process::m_TasksCV; condition_variable Process::m_TasksCV;
Process::Process(const string& command) Process::Process(const String& command)
: AsyncTask<Process, ProcessResult>(), m_Command(command), m_UsePopen(false) : AsyncTask<Process, ProcessResult>(), m_Command(command), m_UsePopen(false)
{ {
if (!m_ThreadCreated) { if (!m_ThreadCreated) {
@ -133,12 +133,12 @@ void Process::InitTask(void)
m_Result.ExecutionStart = Utility::GetTime(); m_Result.ExecutionStart = Utility::GetTime();
#ifdef _MSC_VER #ifdef _MSC_VER
m_FP = _popen(m_Command.c_str(), "r"); m_FP = _popen(m_Command.CStr(), "r");
#else /* _MSC_VER */ #else /* _MSC_VER */
if (!m_UsePopen) { if (!m_UsePopen) {
m_PCloseArg = new popen_noshell_pass_to_pclose; m_PCloseArg = new popen_noshell_pass_to_pclose;
m_FP = popen_noshell_compat(m_Command.c_str(), "r", m_FP = popen_noshell_compat(m_Command.CStr(), "r",
(popen_noshell_pass_to_pclose *)m_PCloseArg); (popen_noshell_pass_to_pclose *)m_PCloseArg);
if (m_FP == NULL) if (m_FP == NULL)
@ -146,7 +146,7 @@ void Process::InitTask(void)
} }
if (m_UsePopen) if (m_UsePopen)
m_FP = popen(m_Command.c_str(), "r"); m_FP = popen(m_Command.CStr(), "r");
#endif /* _MSC_VER */ #endif /* _MSC_VER */
if (m_FP == NULL) if (m_FP == NULL)
@ -164,7 +164,7 @@ bool Process::RunTask(void)
if (!feof(m_FP)) if (!feof(m_FP))
return true; return true;
string output = m_OutputStream.str(); String output = m_OutputStream.str();
int status, exitcode; int status, exitcode;
#ifdef _MSC_VER #ifdef _MSC_VER
@ -189,7 +189,7 @@ bool Process::RunTask(void)
/* cmd.exe returns error code 1 (warning) when the plugin /* cmd.exe returns error code 1 (warning) when the plugin
* could not be executed - change the exit status to "unknown" * could not be executed - change the exit status to "unknown"
* when we have no plugin output. */ * when we have no plugin output. */
if (output.empty()) if (output.IsEmpty())
exitcode = 128; exitcode = 128;
#endif /* _MSC_VER */ #endif /* _MSC_VER */

View File

@ -28,7 +28,7 @@ struct ProcessResult
double ExecutionStart; double ExecutionStart;
double ExecutionEnd; double ExecutionEnd;
long ExitStatus; long ExitStatus;
string Output; String Output;
}; };
class I2_BASE_API Process : public AsyncTask<Process, ProcessResult> class I2_BASE_API Process : public AsyncTask<Process, ProcessResult>
@ -39,12 +39,12 @@ public:
static const int MaxTasksPerThread = 128; static const int MaxTasksPerThread = 128;
Process(const string& command); Process(const String& command);
private: private:
static bool m_ThreadCreated; static bool m_ThreadCreated;
string m_Command; String m_Command;
FILE *m_FP; FILE *m_FP;
stringstream m_OutputStream; stringstream m_OutputStream;

205
base/qstring.cpp Normal file
View File

@ -0,0 +1,205 @@
#include "i2-base.h"
using namespace icinga;
const size_t String::NPos = std::string::npos;
String::String(void)
{ }
String::String(const char *data)
: m_Data(data)
{ }
String::String(const std::string& data)
: m_Data(data)
{ }
String::String(const String& other)
: m_Data(other.m_Data)
{ }
String& String::operator=(const String& rhs)
{
m_Data = rhs.m_Data;
return *this;
}
String& String::operator=(const std::string& rhs)
{
m_Data = rhs;
return *this;
}
String& String::operator=(const char *rhs)
{
m_Data = rhs;
return *this;
}
const char& String::operator[](size_t pos) const
{
return m_Data[pos];
}
char& String::operator[](size_t pos)
{
return m_Data[pos];
}
String& String::operator+=(const String& rhs)
{
m_Data += rhs.m_Data;
return *this;
}
String& String::operator+=(const char *rhs)
{
m_Data += rhs;
return *this;
}
bool String::IsEmpty(void) const
{
return m_Data.empty();
}
bool String::operator<(const String& rhs) const
{
return m_Data < rhs.m_Data;
}
String::operator const std::string&(void) const
{
return m_Data;
}
const char *String::CStr(void) const
{
return m_Data.c_str();
}
void String::Clear(void)
{
m_Data.clear();
}
size_t String::GetLength(void) const
{
return m_Data.size();
}
size_t String::FindFirstOf(const char *s, size_t pos) const
{
return m_Data.find_first_of(s, pos);
}
String String::SubStr(size_t first, size_t second) const
{
return m_Data.substr(first, second);
}
void String::Replace(size_t first, size_t second, const String& str)
{
m_Data.replace(first, second, str);
}
void String::Trim(void)
{
boost::algorithm::trim(m_Data);
}
void String::swap(String& str)
{
m_Data.swap(str.m_Data);
}
String::Iterator String::erase(String::Iterator first, String::Iterator last)
{
return m_Data.erase(first, last);
}
String::Iterator String::Begin(void)
{
return m_Data.begin();
}
String::ConstIterator String::Begin(void) const
{
return m_Data.begin();
}
String::Iterator String::End(void)
{
return m_Data.end();
}
String::ConstIterator String::End(void) const
{
return m_Data.end();
}
ostream& icinga::operator<<(ostream& stream, const String& str)
{
stream << static_cast<std::string>(str);
return stream;
}
istream& icinga::operator>>(istream& stream, String& str)
{
std::string tstr;
stream >> tstr;
str = tstr;
return stream;
}
String icinga::operator+(const String& lhs, const String& rhs)
{
return static_cast<std::string>(lhs) + static_cast<std::string>(rhs);
}
String icinga::operator+(const String& lhs, const char *rhs)
{
return static_cast<std::string>(lhs) + rhs;
}
String icinga::operator+(const char *lhs, const String& rhs)
{
return lhs + static_cast<std::string>(rhs);
}
bool icinga::operator==(const String& lhs, const String& rhs)
{
return static_cast<std::string>(lhs) == static_cast<std::string>(rhs);
}
bool icinga::operator==(const String& lhs, const char *rhs)
{
return static_cast<std::string>(lhs) == rhs;
}
bool icinga::operator==(const char *lhs, const String& rhs)
{
return lhs == static_cast<std::string>(rhs);
}
String::Iterator icinga::range_begin(String& x)
{
return x.Begin();
}
String::ConstIterator icinga::range_begin(const String& x)
{
return x.Begin();
}
String::Iterator icinga::range_end(String& x)
{
return x.End();
}
String::ConstIterator icinga::range_end(const String& x)
{
return x.End();
}

112
base/qstring.h Normal file
View File

@ -0,0 +1,112 @@
#ifndef STRING_H
#define STRING_H
namespace icinga {
/**
* String class.
*
* Rationale: The std::string class has an ambiguous assignment
* operator when used in conjunction with the Value class.
*/
class I2_BASE_API String
{
public:
typedef std::string::iterator Iterator;
typedef std::string::const_iterator ConstIterator;
String(void);
String(const char *data);
String(const std::string& data);
template<typename InputIterator>
String(InputIterator begin, InputIterator end)
: m_Data(begin, end)
{ }
String(const String& other);
String& operator=(const String& rhs);
String& operator=(const std::string& rhs);
String& operator=(const char *rhs);
const char& operator[](size_t pos) const;
char& operator[](size_t pos);
String& operator+=(const String& rhs);
String& operator+=(const char *rhs);
bool IsEmpty(void) const;
bool operator<(const String& rhs) const;
operator const std::string&(void) const;
const char *CStr(void) const;
void Clear(void);
size_t GetLength(void) const;
size_t FindFirstOf(const char *s, size_t pos = 0) const;
String SubStr(size_t first, size_t second) const;
void Replace(size_t first, size_t second, const String& str);
template<typename Predicate>
vector<String> Split(const Predicate& predicate)
{
vector<String> tokens;
boost::algorithm::split(tokens, m_Data, predicate);
return tokens;
}
void Trim(void);
void swap(String& str);
Iterator erase(Iterator first, Iterator last);
Iterator Begin(void);
ConstIterator Begin(void) const;
Iterator End(void);
ConstIterator End(void) const;
static const size_t NPos;
private:
std::string m_Data;
};
I2_BASE_API ostream& operator<<(ostream& stream, const String& str);
I2_BASE_API istream& operator>>(istream& stream, String& str);
I2_BASE_API String operator+(const String& lhs, const String& rhs);
I2_BASE_API String operator+(const String& lhs, const char *rhs);
I2_BASE_API String operator+(const char *lhs, const String& rhs);
I2_BASE_API bool operator==(const String& lhs, const String& rhs);
I2_BASE_API bool operator==(const String& lhs, const char *rhs);
I2_BASE_API bool operator==(const char *lhs, const String& rhs);
I2_BASE_API String::Iterator range_begin(String& x);
I2_BASE_API String::ConstIterator range_begin(const String& x);
I2_BASE_API String::Iterator range_end(String& x);
I2_BASE_API String::ConstIterator range_end(const String& x);
}
namespace boost
{
template<>
struct range_mutable_iterator<icinga::String>
{
typedef icinga::String::Iterator type;
};
template<>
struct range_const_iterator<icinga::String>
{
typedef icinga::String::ConstIterator type;
};
}
#endif /* STRING_H */

View File

@ -2,25 +2,25 @@
using namespace icinga; using namespace icinga;
map<string, ScriptFunction::Ptr> ScriptFunction::m_Functions; map<String, ScriptFunction::Ptr> ScriptFunction::m_Functions;
ScriptFunction::ScriptFunction(const Callback& function) ScriptFunction::ScriptFunction(const Callback& function)
: m_Callback(function) : m_Callback(function)
{ } { }
void ScriptFunction::Register(const string& name, const ScriptFunction::Ptr& function) void ScriptFunction::Register(const String& name, const ScriptFunction::Ptr& function)
{ {
m_Functions[name] = function; m_Functions[name] = function;
} }
void ScriptFunction::Unregister(const string& name) void ScriptFunction::Unregister(const String& name)
{ {
m_Functions.erase(name); m_Functions.erase(name);
} }
ScriptFunction::Ptr ScriptFunction::GetByName(const string& name) ScriptFunction::Ptr ScriptFunction::GetByName(const String& name)
{ {
map<string, ScriptFunction::Ptr>::iterator it; map<String, ScriptFunction::Ptr>::iterator it;
it = m_Functions.find(name); it = m_Functions.find(name);
@ -30,7 +30,7 @@ ScriptFunction::Ptr ScriptFunction::GetByName(const string& name)
return it->second; return it->second;
} }
void ScriptFunction::Invoke(const ScriptTask::Ptr& task, const vector<Variant>& arguments) void ScriptFunction::Invoke(const ScriptTask::Ptr& task, const vector<Value>& arguments)
{ {
m_Callback(task, arguments); m_Callback(task, arguments);
} }

View File

@ -31,20 +31,20 @@ public:
typedef shared_ptr<ScriptFunction> Ptr; typedef shared_ptr<ScriptFunction> Ptr;
typedef weak_ptr<ScriptFunction> WeakPtr; typedef weak_ptr<ScriptFunction> WeakPtr;
typedef function<void (const shared_ptr<ScriptTask>&, const vector<Variant>& arguments)> Callback; typedef function<void (const shared_ptr<ScriptTask>&, const vector<Value>& arguments)> Callback;
ScriptFunction(const Callback& function); ScriptFunction(const Callback& function);
static void Register(const string& name, const ScriptFunction::Ptr& function); static void Register(const String& name, const ScriptFunction::Ptr& function);
static void Unregister(const string& name); static void Unregister(const String& name);
static ScriptFunction::Ptr GetByName(const string& name); static ScriptFunction::Ptr GetByName(const String& name);
void Invoke(const shared_ptr<ScriptTask>& task, const vector<Variant>& arguments); void Invoke(const shared_ptr<ScriptTask>& task, const vector<Value>& arguments);
private: private:
Callback m_Callback; Callback m_Callback;
static map<string, ScriptFunction::Ptr> m_Functions; static map<String, ScriptFunction::Ptr> m_Functions;
}; };
} }

View File

@ -2,8 +2,8 @@
using namespace icinga; using namespace icinga;
ScriptTask::ScriptTask(const ScriptFunction::Ptr& function, const vector<Variant>& arguments) ScriptTask::ScriptTask(const ScriptFunction::Ptr& function, const vector<Value>& arguments)
: AsyncTask<ScriptTask, Variant>(), m_Function(function), m_Arguments(arguments) : AsyncTask<ScriptTask, Value>(), m_Function(function), m_Arguments(arguments)
{ } { }
void ScriptTask::Run(void) void ScriptTask::Run(void)

View File

@ -23,20 +23,20 @@
namespace icinga namespace icinga
{ {
class I2_BASE_API ScriptTask : public AsyncTask<ScriptTask, Variant> class I2_BASE_API ScriptTask : public AsyncTask<ScriptTask, Value>
{ {
public: public:
typedef shared_ptr<ScriptTask> Ptr; typedef shared_ptr<ScriptTask> Ptr;
typedef weak_ptr<ScriptTask> WeakPtr; typedef weak_ptr<ScriptTask> WeakPtr;
ScriptTask(const ScriptFunction::Ptr& function, const vector<Variant>& arguments); ScriptTask(const ScriptFunction::Ptr& function, const vector<Value>& arguments);
protected: protected:
virtual void Run(void); virtual void Run(void);
private: private:
ScriptFunction::Ptr m_Function; ScriptFunction::Ptr m_Function;
vector<Variant> m_Arguments; vector<Value> m_Arguments;
}; };
} }

View File

@ -185,9 +185,9 @@ void Socket::HandleWritable(void)
/** /**
* Formats a sockaddr in a human-readable way. * Formats a sockaddr in a human-readable way.
* *
* @returns A string describing the sockaddr. * @returns A String describing the sockaddr.
*/ */
string Socket::GetAddressFromSockaddr(sockaddr *address, socklen_t len) String Socket::GetAddressFromSockaddr(sockaddr *address, socklen_t len)
{ {
char host[NI_MAXHOST]; char host[NI_MAXHOST];
char service[NI_MAXSERV]; char service[NI_MAXSERV];
@ -203,11 +203,11 @@ string Socket::GetAddressFromSockaddr(sockaddr *address, socklen_t len)
} }
/** /**
* Returns a string describing the local address of the socket. * Returns a String describing the local address of the socket.
* *
* @returns A string describing the local address. * @returns A String describing the local address.
*/ */
string Socket::GetClientAddress(void) String Socket::GetClientAddress(void)
{ {
mutex::scoped_lock lock(m_Mutex); mutex::scoped_lock lock(m_Mutex);
@ -221,11 +221,11 @@ string Socket::GetClientAddress(void)
} }
/** /**
* Returns a string describing the peer address of the socket. * Returns a String describing the peer address of the socket.
* *
* @returns A string describing the peer address. * @returns A String describing the peer address.
*/ */
string Socket::GetPeerAddress(void) String Socket::GetPeerAddress(void)
{ {
mutex::scoped_lock lock(m_Mutex); mutex::scoped_lock lock(m_Mutex);
@ -244,16 +244,16 @@ string Socket::GetPeerAddress(void)
* @param message The error message. * @param message The error message.
* @param errorCode The error code. * @param errorCode The error code.
*/ */
SocketException::SocketException(const string& message, int errorCode) SocketException::SocketException(const String& message, int errorCode)
{ {
#ifdef _WIN32 #ifdef _WIN32
string details = Win32Exception::FormatErrorCode(errorCode); String details = Win32Exception::FormatErrorCode(errorCode);
#else /* _WIN32 */ #else /* _WIN32 */
string details = PosixException::FormatErrorCode(errorCode); String details = PosixException::FormatErrorCode(errorCode);
#endif /* _WIN32 */ #endif /* _WIN32 */
string msg = message + ": " + details; String msg = message + ": " + details;
SetMessage(msg.c_str()); SetMessage(msg.CStr());
} }
void Socket::ReadThreadProc(void) void Socket::ReadThreadProc(void)

View File

@ -41,8 +41,8 @@ public:
void Close(void); void Close(void);
string GetClientAddress(void); String GetClientAddress(void);
string GetPeerAddress(void); String GetPeerAddress(void);
mutex& GetMutex(void) const; mutex& GetMutex(void) const;
@ -87,7 +87,7 @@ private:
void ExceptionEventHandler(void); void ExceptionEventHandler(void);
static string GetAddressFromSockaddr(sockaddr *address, socklen_t len); static String GetAddressFromSockaddr(sockaddr *address, socklen_t len);
}; };
/** /**
@ -96,7 +96,7 @@ private:
class SocketException : public Exception class SocketException : public Exception
{ {
public: public:
SocketException(const string& message, int errorCode); SocketException(const String& message, int errorCode);
}; };
} }

View File

@ -28,12 +28,12 @@ StreamLogger::~StreamLogger(void)
delete m_Stream; delete m_Stream;
} }
void StreamLogger::OpenFile(const string& filename) void StreamLogger::OpenFile(const String& filename)
{ {
ofstream *stream = new ofstream(); ofstream *stream = new ofstream();
try { try {
stream->open(filename.c_str(), ofstream::out | ofstream::trunc); stream->open(filename.CStr(), ofstream::out | ofstream::trunc);
if (!stream->good()) if (!stream->good())
throw_exception(runtime_error("Could not open logfile '" + filename + "'")); throw_exception(runtime_error("Could not open logfile '" + filename + "'"));

View File

@ -17,7 +17,7 @@ public:
StreamLogger(std::ostream *stream); StreamLogger(std::ostream *stream);
~StreamLogger(void); ~StreamLogger(void);
void OpenFile(const string& filename); void OpenFile(const String& filename);
protected: protected:
virtual void ProcessLogEntry(const LogEntry& entry); virtual void ProcessLogEntry(const LogEntry& entry);

View File

@ -30,6 +30,6 @@ void SyslogLogger::ProcessLogEntry(const LogEntry& entry)
assert(!"Invalid severity specified."); assert(!"Invalid severity specified.");
} }
syslog(severity | LOG_USER, "%s", entry.Message.c_str()); syslog(severity | LOG_USER, "%s", entry.Message.CStr());
} }
#endif /* _WIN32 */ #endif /* _WIN32 */

View File

@ -47,7 +47,7 @@ TcpClientRole TcpClient::GetRole(void) const
* @param node The node. * @param node The node.
* @param service The service. * @param service The service.
*/ */
void TcpClient::Connect(const string& node, const string& service) void TcpClient::Connect(const String& node, const String& service)
{ {
m_Role = RoleOutbound; m_Role = RoleOutbound;
@ -59,7 +59,7 @@ void TcpClient::Connect(const string& node, const string& service)
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP; hints.ai_protocol = IPPROTO_TCP;
int rc = getaddrinfo(node.c_str(), service.c_str(), &hints, &result); int rc = getaddrinfo(node.CStr(), service.CStr(), &hints, &result);
if (rc < 0) if (rc < 0)
throw_exception(SocketException("getaddrinfo() failed", GetLastSocketError())); throw_exception(SocketException("getaddrinfo() failed", GetLastSocketError()));

View File

@ -51,7 +51,7 @@ public:
TcpClientRole GetRole(void) const; TcpClientRole GetRole(void) const;
void Connect(const string& node, const string& service); void Connect(const String& node, const String& service);
boost::signal<void (const TcpClient::Ptr&)> OnConnected; boost::signal<void (const TcpClient::Ptr&)> OnConnected;
boost::signal<void (const TcpClient::Ptr&)> OnDataAvailable; boost::signal<void (const TcpClient::Ptr&)> OnDataAvailable;

View File

@ -44,9 +44,9 @@ void TcpSocket::MakeSocket(int family)
* @param service The service. * @param service The service.
* @param family The address family for the socket. * @param family The address family for the socket.
*/ */
void TcpSocket::Bind(string service, int family) void TcpSocket::Bind(String service, int family)
{ {
Bind(string(), service, family); Bind(String(), service, family);
} }
/** /**
@ -56,7 +56,7 @@ void TcpSocket::Bind(string service, int family)
* @param service The service. * @param service The service.
* @param family The address family for the socket. * @param family The address family for the socket.
*/ */
void TcpSocket::Bind(string node, string service, int family) void TcpSocket::Bind(String node, String service, int family)
{ {
addrinfo hints; addrinfo hints;
addrinfo *result; addrinfo *result;
@ -67,8 +67,8 @@ void TcpSocket::Bind(string node, string service, int family)
hints.ai_protocol = IPPROTO_TCP; hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE; hints.ai_flags = AI_PASSIVE;
if (getaddrinfo(node.empty() ? NULL : node.c_str(), if (getaddrinfo(node.IsEmpty() ? NULL : node.CStr(),
service.c_str(), &hints, &result) < 0) service.CStr(), &hints, &result) < 0)
throw_exception(SocketException("getaddrinfo() failed", GetLastSocketError())); throw_exception(SocketException("getaddrinfo() failed", GetLastSocketError()));
int fd = INVALID_SOCKET; int fd = INVALID_SOCKET;

View File

@ -34,8 +34,8 @@ public:
typedef shared_ptr<TcpSocket> Ptr; typedef shared_ptr<TcpSocket> Ptr;
typedef weak_ptr<TcpSocket> WeakPtr; typedef weak_ptr<TcpSocket> WeakPtr;
void Bind(string service, int family); void Bind(String service, int family);
void Bind(string node, string service, int family); void Bind(String node, String service, int family);
private: private:
void MakeSocket(int family); void MakeSocket(int family);

View File

@ -30,16 +30,16 @@ bool I2_EXPORT Utility::m_SSLInitialized = false;
* @param ti A type_info object. * @param ti A type_info object.
* @returns The type name of the object. * @returns The type name of the object.
*/ */
string Utility::GetTypeName(const type_info& ti) String Utility::GetTypeName(const type_info& ti)
{ {
string klass = ti.name(); String klass = ti.name();
#ifdef HAVE_GCC_ABI_DEMANGLE #ifdef HAVE_GCC_ABI_DEMANGLE
int status; int status;
char *realname = abi::__cxa_demangle(klass.c_str(), 0, 0, &status); char *realname = abi::__cxa_demangle(klass.CStr(), 0, 0, &status);
if (realname != NULL) { if (realname != NULL) {
klass = string(realname); klass = String(realname);
free(realname); free(realname);
} }
#endif /* HAVE_GCC_ABI_DEMANGLE */ #endif /* HAVE_GCC_ABI_DEMANGLE */
@ -107,7 +107,7 @@ void Utility::InitializeOpenSSL(void)
* @param cakey CA certificate chain file. * @param cakey CA certificate chain file.
* @returns An SSL context. * @returns An SSL context.
*/ */
shared_ptr<SSL_CTX> Utility::MakeSSLContext(string pubkey, string privkey, string cakey) shared_ptr<SSL_CTX> Utility::MakeSSLContext(String pubkey, String privkey, String cakey)
{ {
InitializeOpenSSL(); InitializeOpenSSL();
@ -115,18 +115,18 @@ shared_ptr<SSL_CTX> Utility::MakeSSLContext(string pubkey, string privkey, strin
SSL_CTX_set_mode(sslContext.get(), SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); SSL_CTX_set_mode(sslContext.get(), SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
if (!SSL_CTX_use_certificate_chain_file(sslContext.get(), pubkey.c_str())) if (!SSL_CTX_use_certificate_chain_file(sslContext.get(), pubkey.CStr()))
throw_exception(OpenSSLException("Could not load public X509 key file", ERR_get_error())); throw_exception(OpenSSLException("Could not load public X509 key file", ERR_get_error()));
if (!SSL_CTX_use_PrivateKey_file(sslContext.get(), privkey.c_str(), SSL_FILETYPE_PEM)) if (!SSL_CTX_use_PrivateKey_file(sslContext.get(), privkey.CStr(), SSL_FILETYPE_PEM))
throw_exception(OpenSSLException("Could not load private X509 key file", ERR_get_error())); throw_exception(OpenSSLException("Could not load private X509 key file", ERR_get_error()));
if (!SSL_CTX_load_verify_locations(sslContext.get(), cakey.c_str(), NULL)) if (!SSL_CTX_load_verify_locations(sslContext.get(), cakey.CStr(), NULL))
throw_exception(OpenSSLException("Could not load public CA key file", ERR_get_error())); throw_exception(OpenSSLException("Could not load public CA key file", ERR_get_error()));
STACK_OF(X509_NAME) *cert_names; STACK_OF(X509_NAME) *cert_names;
cert_names = SSL_load_client_CA_file(cakey.c_str()); cert_names = SSL_load_client_CA_file(cakey.CStr());
if (cert_names == NULL) if (cert_names == NULL)
throw_exception(OpenSSLException("SSL_load_client_CA_file() failed", ERR_get_error())); throw_exception(OpenSSLException("SSL_load_client_CA_file() failed", ERR_get_error()));
@ -141,7 +141,7 @@ shared_ptr<SSL_CTX> Utility::MakeSSLContext(string pubkey, string privkey, strin
* @param certificate The X509 certificate. * @param certificate The X509 certificate.
* @returns The common name. * @returns The common name.
*/ */
string Utility::GetCertificateCN(const shared_ptr<X509>& certificate) String Utility::GetCertificateCN(const shared_ptr<X509>& certificate)
{ {
char buffer[256]; char buffer[256];
@ -159,7 +159,7 @@ string Utility::GetCertificateCN(const shared_ptr<X509>& certificate)
* @param pemfile The filename. * @param pemfile The filename.
* @returns An X509 certificate. * @returns An X509 certificate.
*/ */
shared_ptr<X509> Utility::GetX509Certificate(string pemfile) shared_ptr<X509> Utility::GetX509Certificate(String pemfile)
{ {
X509 *cert; X509 *cert;
BIO *fpcert = BIO_new(BIO_s_file()); BIO *fpcert = BIO_new(BIO_s_file());
@ -167,7 +167,7 @@ shared_ptr<X509> Utility::GetX509Certificate(string pemfile)
if (fpcert == NULL) if (fpcert == NULL)
throw_exception(OpenSSLException("BIO_new failed", ERR_get_error())); throw_exception(OpenSSLException("BIO_new failed", ERR_get_error()));
if (BIO_read_filename(fpcert, pemfile.c_str()) < 0) if (BIO_read_filename(fpcert, pemfile.CStr()) < 0)
throw_exception(OpenSSLException("BIO_read_filename failed", ERR_get_error())); throw_exception(OpenSSLException("BIO_read_filename failed", ERR_get_error()));
cert = PEM_read_bio_X509_AUX(fpcert, NULL, NULL, NULL); cert = PEM_read_bio_X509_AUX(fpcert, NULL, NULL, NULL);
@ -183,12 +183,12 @@ shared_ptr<X509> Utility::GetX509Certificate(string pemfile)
* Performs wildcard pattern matching. * Performs wildcard pattern matching.
* *
* @param pattern The wildcard pattern. * @param pattern The wildcard pattern.
* @param text The string that should be checked. * @param text The String that should be checked.
* @returns true if the wildcard pattern matches, false otherwise. * @returns true if the wildcard pattern matches, false otherwise.
*/ */
bool Utility::Match(string pattern, string text) bool Utility::Match(String pattern, String text)
{ {
return (match(pattern.c_str(), text.c_str()) == 0); return (match(pattern.CStr(), text.CStr()) == 0);
} }
/** /**
@ -197,10 +197,10 @@ bool Utility::Match(string pattern, string text)
* @param path The full path. * @param path The full path.
* @returns The directory. * @returns The directory.
*/ */
string Utility::DirName(const string& path) String Utility::DirName(const String& path)
{ {
char *dir = strdup(path.c_str()); char *dir = strdup(path.CStr());
string result; String result;
if (dir == NULL) if (dir == NULL)
throw_exception(bad_alloc()); throw_exception(bad_alloc());
@ -227,10 +227,10 @@ string Utility::DirName(const string& path)
* @param path The full path. * @param path The full path.
* @returns The filename. * @returns The filename.
*/ */
string Utility::BaseName(const string& path) String Utility::BaseName(const String& path)
{ {
char *dir = strdup(path.c_str()); char *dir = strdup(path.CStr());
string result; String result;
if (dir == NULL) if (dir == NULL)
throw_exception(bad_alloc()); throw_exception(bad_alloc());

View File

@ -31,18 +31,18 @@ namespace icinga
class I2_BASE_API Utility class I2_BASE_API Utility
{ {
public: public:
static string GetTypeName(const type_info& ti); static String GetTypeName(const type_info& ti);
static void Daemonize(void); static void Daemonize(void);
static shared_ptr<SSL_CTX> MakeSSLContext(string pubkey, string privkey, string cakey); static shared_ptr<SSL_CTX> MakeSSLContext(String pubkey, String privkey, String cakey);
static string GetCertificateCN(const shared_ptr<X509>& certificate); static String GetCertificateCN(const shared_ptr<X509>& certificate);
static shared_ptr<X509> GetX509Certificate(string pemfile); static shared_ptr<X509> GetX509Certificate(String pemfile);
static bool Match(string pattern, string text); static bool Match(String pattern, String text);
static string DirName(const string& path); static String DirName(const String& path);
static string BaseName(const string& path); static String BaseName(const String& path);
static void NullDeleter(void *obj); static void NullDeleter(void *obj);

View File

@ -27,27 +27,27 @@ using namespace icinga;
* *
* @returns true if the variant is empty, false otherwise. * @returns true if the variant is empty, false otherwise.
*/ */
bool Variant::IsEmpty(void) const bool Value::IsEmpty(void) const
{ {
return (m_Value.type() == typeid(boost::blank)); return (m_Value.type() == typeid(boost::blank));
} }
bool Variant::IsScalar(void) const bool Value::IsScalar(void) const
{ {
return !IsEmpty() && !IsObject(); return !IsEmpty() && !IsObject();
} }
bool Variant::IsObject(void) const bool Value::IsObject(void) const
{ {
return !IsEmpty() && (m_Value.type() == typeid(Object::Ptr)); return !IsEmpty() && (m_Value.type() == typeid(Object::Ptr));
} }
Variant Variant::FromJson(cJSON *json) Value Value::FromJson(cJSON *json)
{ {
if (json->type == cJSON_Number) if (json->type == cJSON_Number)
return json->valuedouble; return json->valuedouble;
else if (json->type == cJSON_String) else if (json->type == cJSON_String)
return json->valuestring; return String(json->valuestring);
else if (json->type == cJSON_True) else if (json->type == cJSON_True)
return 1; return 1;
else if (json->type == cJSON_False) else if (json->type == cJSON_False)
@ -55,39 +55,39 @@ Variant Variant::FromJson(cJSON *json)
else if (json->type == cJSON_Object) else if (json->type == cJSON_Object)
return Dictionary::FromJson(json); return Dictionary::FromJson(json);
else if (json->type == cJSON_NULL) else if (json->type == cJSON_NULL)
return Variant(); return Value();
else else
throw_exception(invalid_argument("Unsupported JSON type.")); throw_exception(invalid_argument("Unsupported JSON type."));
} }
string Variant::Serialize(void) const String Value::Serialize(void) const
{ {
cJSON *json = ToJson(); cJSON *json = ToJson();
char *jsonString; char *jsonString;
if (!Application::GetInstance()->IsDebugging()) if (Application::GetInstance()->IsDebugging())
jsonString = cJSON_Print(json); jsonString = cJSON_Print(json);
else else
jsonString = cJSON_PrintUnformatted(json); jsonString = cJSON_PrintUnformatted(json);
cJSON_Delete(json); cJSON_Delete(json);
string result = jsonString; String result = jsonString;
free(jsonString); free(jsonString);
return result; return result;
} }
cJSON *Variant::ToJson(void) const cJSON *Value::ToJson(void) const
{ {
if (m_Value.type() == typeid(long)) { if (m_Value.type() == typeid(long)) {
return cJSON_CreateNumber(boost::get<long>(m_Value)); return cJSON_CreateNumber(boost::get<long>(m_Value));
} else if (m_Value.type() == typeid(double)) { } else if (m_Value.type() == typeid(double)) {
return cJSON_CreateNumber(boost::get<double>(m_Value)); return cJSON_CreateNumber(boost::get<double>(m_Value));
} else if (m_Value.type() == typeid(string)) { } else if (m_Value.type() == typeid(String)) {
return cJSON_CreateString(boost::get<string>(m_Value).c_str()); return cJSON_CreateString(boost::get<String>(m_Value).CStr());
} else if (m_Value.type() == typeid(Object::Ptr)) { } else if (m_Value.type() == typeid(Object::Ptr)) {
if (IsObjectType<Dictionary>()) { if (IsObjectType<Dictionary>()) {
Dictionary::Ptr dictionary = *this; Dictionary::Ptr dictionary = *this;
@ -103,14 +103,14 @@ cJSON *Variant::ToJson(void) const
} }
} }
Variant Variant::Deserialize(const string& jsonString) Value Value::Deserialize(const String& jsonString)
{ {
cJSON *json = cJSON_Parse(jsonString.c_str()); cJSON *json = cJSON_Parse(jsonString.CStr());
if (!json) if (!json)
throw_exception(runtime_error("Invalid JSON string")); throw_exception(runtime_error("Invalid JSON String"));
Variant value = FromJson(json); Value value = FromJson(json);
cJSON_Delete(json); cJSON_Delete(json);
return value; return value;

View File

@ -17,8 +17,8 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/ ******************************************************************************/
#ifndef VARIANT_H #ifndef VALUE_H
#define VARIANT_H #define VALUE_H
struct cJSON; struct cJSON;
@ -30,40 +30,40 @@ namespace icinga
* *
* @ingroup base * @ingroup base
*/ */
class I2_BASE_API Variant class I2_BASE_API Value
{ {
public: public:
inline Variant(void) inline Value(void)
: m_Value() : m_Value()
{ } { }
inline Variant(int value) inline Value(int value)
: m_Value(static_cast<long>(value))
{ }
inline Variant(long value)
: m_Value(value) : m_Value(value)
{ } { }
inline Variant(double value) inline Value(long value)
: m_Value(double(value))
{ }
inline Value(double value)
: m_Value(value) : m_Value(value)
{ } { }
inline Variant(bool value) inline Value(const String& value)
: m_Value(static_cast<long>(value))
{ }
inline Variant(const string& value)
: m_Value(value) : m_Value(value)
{ } { }
inline Variant(const char *value) inline Value(const char *value)
: m_Value(string(value)) : m_Value(String(value))
{ } { }
template<typename T> template<typename T>
inline Variant(const shared_ptr<T>& value) inline Value(const shared_ptr<T>& value)
: m_Value()
{ {
if (!value)
return;
Object::Ptr object = dynamic_pointer_cast<Object>(value); Object::Ptr object = dynamic_pointer_cast<Object>(value);
if (!object) if (!object)
@ -72,20 +72,6 @@ public:
m_Value = object; m_Value = object;
} }
operator long(void) const
{
if (m_Value.type() != typeid(long)) {
if (m_Value.type() == typeid(double)) {
// TODO: log this?
return boost::get<double>(m_Value);
} else {
return boost::lexical_cast<long>(m_Value);
}
} else {
return boost::get<long>(m_Value);
}
}
operator double(void) const operator double(void) const
{ {
if (m_Value.type() != typeid(double)) { if (m_Value.type() != typeid(double)) {
@ -95,20 +81,17 @@ public:
} }
} }
operator bool(void) const operator String(void) const
{ {
return (static_cast<long>(*this) != 0); if (IsEmpty())
} return String();
operator string(void) const if (m_Value.type() != typeid(String)) {
{ String result = boost::lexical_cast<String>(m_Value);
if (m_Value.type() != typeid(string)) {
string result = boost::lexical_cast<string>(m_Value);
m_Value = result; m_Value = result;
return result;
} else {
return boost::get<string>(m_Value);
} }
return boost::get<String>(m_Value);
} }
template<typename T> template<typename T>
@ -138,16 +121,16 @@ public:
return (dynamic_pointer_cast<T>(boost::get<Object::Ptr>(m_Value))); return (dynamic_pointer_cast<T>(boost::get<Object::Ptr>(m_Value)));
} }
static Variant FromJson(cJSON *json); static Value FromJson(cJSON *json);
cJSON *ToJson(void) const; cJSON *ToJson(void) const;
string Serialize(void) const; String Serialize(void) const;
static Variant Deserialize(const string& jsonString); static Value Deserialize(const String& jsonString);
private: private:
mutable boost::variant<boost::blank, long, double, string, Object::Ptr> m_Value; mutable boost::variant<boost::blank, double, String, Object::Ptr> m_Value;
}; };
} }
#endif /* VARIANT_H */ #endif /* VALUE_H */

View File

@ -4,7 +4,6 @@ pkglib_LTLIBRARIES = \
libcib.la libcib.la
libcib_la_SOURCES = \ libcib_la_SOURCES = \
checkresult.cpp \
checkresult.h \ checkresult.h \
checkresultmessage.cpp \ checkresultmessage.cpp \
checkresultmessage.h \ checkresultmessage.h \

View File

@ -1,126 +0,0 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#include "i2-cib.h"
using namespace icinga;
CheckResult::CheckResult(void)
: MessagePart()
{ }
CheckResult::CheckResult(const MessagePart& message)
: MessagePart(message)
{ }
void CheckResult::SetScheduleStart(double ts)
{
Set("schedule_start", ts);
}
double CheckResult::GetScheduleStart(void) const
{
double value = 0;
Get("schedule_start", &value);
return value;
}
void CheckResult::SetScheduleEnd(double ts)
{
Set("schedule_end", ts);
}
double CheckResult::GetScheduleEnd(void) const
{
double value = 0;
Get("schedule_end", &value);
return value;
}
void CheckResult::SetExecutionStart(double ts)
{
Set("execution_start", ts);
}
double CheckResult::GetExecutionStart(void) const
{
double value = 0;
Get("execution_start", &value);
return value;
}
void CheckResult::SetExecutionEnd(double ts)
{
Set("execution_end", ts);
}
double CheckResult::GetExecutionEnd(void) const
{
double value = 0;
Get("execution_end", &value);
return value;
}
void CheckResult::SetState(ServiceState state)
{
Set("state", static_cast<long>(state));
}
ServiceState CheckResult::GetState(void) const
{
long value = StateUnknown;
Get("state", &value);
return static_cast<ServiceState>(value);
}
void CheckResult::SetOutput(string output)
{
Set("output", output);
}
string CheckResult::GetOutput(void) const
{
string value;
Get("output", &value);
return value;
}
void CheckResult::SetPerformanceDataRaw(const string& pd)
{
Set("performance_data_raw", pd);
}
string CheckResult::GetPerformanceDataRaw(void) const
{
string value;
Get("performance_data_raw", &value);
return value;
}
void CheckResult::SetPerformanceData(const Dictionary::Ptr& pd)
{
Set("performance_data", pd);
}
Dictionary::Ptr CheckResult::GetPerformanceData(void) const
{
Dictionary::Ptr value;
Get("performance_data", &value);
return value;
}

View File

@ -23,36 +23,20 @@
namespace icinga namespace icinga
{ {
class I2_CIB_API CheckResult : public MessagePart /*struct CheckResult
{ {
public: static const char *ScheduleStart = "schedule_start";
CheckResult(void); static const char *ScheduleEnd = "schedule_end";
CheckResult(const MessagePart& message); static const char *ExecutionStart = "execution_start";
static const char *ExecutionEnd = "execution_end";
static const char *State = "state";
static const char *Output = "output";
static const char *PerformanceDataRaw = "performance_data_raw";
static const char *PerformanceData = "performance_data";
void SetScheduleStart(double ts); private:
double GetScheduleStart(void) const; CheckResult();
};*/
void SetScheduleEnd(double ts);
double GetScheduleEnd(void) const;
void SetExecutionStart(double ts);
double GetExecutionStart(void) const;
void SetExecutionEnd(double ts);
double GetExecutionEnd(void) const;
void SetState(ServiceState state);
ServiceState GetState(void) const;
void SetOutput(string output);
string GetOutput(void) const;
void SetPerformanceDataRaw(const string& pd);
string GetPerformanceDataRaw(void) const;
void SetPerformanceData(const Dictionary::Ptr& pd);
Dictionary::Ptr GetPerformanceData(void) const;
};
} }

View File

@ -21,27 +21,13 @@
using namespace icinga; using namespace icinga;
bool CheckResultMessage::GetService(string *service) const bool CheckResultMessage::GetService(String *service) const
{ {
return Get("service", service); return Get("service", service);
} }
void CheckResultMessage::SetService(const string& service) void CheckResultMessage::SetService(const String& service)
{ {
Set("service", service); Set("service", service);
} }
bool CheckResultMessage::GetCheckResult(CheckResult *cr) const
{
Dictionary::Ptr obj;
if (Get("result", &obj)) {
*cr = CheckResult(MessagePart(obj));
return true;
}
return false;
}
void CheckResultMessage::SetCheckResult(CheckResult cr)
{
Set("result", cr.GetDictionary());
}

View File

@ -29,11 +29,8 @@ public:
CheckResultMessage(void) : MessagePart() { } CheckResultMessage(void) : MessagePart() { }
CheckResultMessage(const MessagePart& message) : MessagePart(message) { } CheckResultMessage(const MessagePart& message) : MessagePart(message) { }
bool GetService(string *service) const; bool GetService(String *service) const;
void SetService(const string& service); void SetService(const String& service);
bool GetCheckResult(CheckResult *cr) const;
void SetCheckResult(CheckResult cr);
}; };
} }

View File

@ -82,7 +82,6 @@
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="checkresult.h" />
<ClInclude Include="cib.h" /> <ClInclude Include="cib.h" />
<ClInclude Include="host.h" /> <ClInclude Include="host.h" />
<ClInclude Include="hostgroup.h" /> <ClInclude Include="hostgroup.h" />
@ -95,7 +94,6 @@
<ClInclude Include="checkresultmessage.h" /> <ClInclude Include="checkresultmessage.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="checkresult.cpp" />
<ClCompile Include="cib.cpp" /> <ClCompile Include="cib.cpp" />
<ClCompile Include="host.cpp" /> <ClCompile Include="host.cpp" />
<ClCompile Include="hostgroup.cpp" /> <ClCompile Include="hostgroup.cpp" />

View File

@ -11,9 +11,6 @@
</Filter> </Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="checkresult.h">
<Filter>Headerdateien</Filter>
</ClInclude>
<ClInclude Include="cib.h"> <ClInclude Include="cib.h">
<Filter>Headerdateien</Filter> <Filter>Headerdateien</Filter>
</ClInclude> </ClInclude>
@ -46,9 +43,6 @@
</ClInclude> </ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="checkresult.cpp">
<Filter>Quelldateien</Filter>
</ClCompile>
<ClCompile Include="cib.cpp"> <ClCompile Include="cib.cpp">
<Filter>Quelldateien</Filter> <Filter>Quelldateien</Filter>
</ClCompile> </ClCompile>

View File

@ -23,22 +23,28 @@ using namespace icinga;
REGISTER_CLASS(Host); REGISTER_CLASS(Host);
string Host::GetAlias(void) const Host::Host(const Dictionary::Ptr& properties)
: DynamicObject(properties)
{ {
string value; RegisterAttribute("alias", Attribute_Config);
RegisterAttribute("hostgroups", Attribute_Config);
if (GetProperty("alias", &value))
return value;
return GetName();
} }
bool Host::Exists(const string& name) String Host::GetAlias(void) const
{
String value;
if (GetAttribute("alias", &value))
return value;
else
return GetName();
}
bool Host::Exists(const String& name)
{ {
return (DynamicObject::GetObject("Host", name)); return (DynamicObject::GetObject("Host", name));
} }
Host::Ptr Host::GetByName(const string& name) Host::Ptr Host::GetByName(const String& name)
{ {
DynamicObject::Ptr configObject = DynamicObject::GetObject("Host", name); DynamicObject::Ptr configObject = DynamicObject::GetObject("Host", name);
@ -51,24 +57,24 @@ Host::Ptr Host::GetByName(const string& name)
Dictionary::Ptr Host::GetGroups(void) const Dictionary::Ptr Host::GetGroups(void) const
{ {
Dictionary::Ptr value; Dictionary::Ptr value;
GetProperty("hostgroups", &value); GetAttribute("hostgroups", &value);
return value; return value;
} }
set<string> Host::GetParents(void) set<String> Host::GetParents(void)
{ {
set<string> parents; set<String> parents;
Dictionary::Ptr dependencies; Dictionary::Ptr dependencies;
GetAttribute("dependencies", &dependencies);
if (GetProperty("dependencies", &dependencies)) { if (dependencies) {
dependencies = Service::ResolveDependencies(GetSelf(), dependencies); dependencies = Service::ResolveDependencies(GetSelf(), dependencies);
Variant dependency; Value dependency;
BOOST_FOREACH(tie(tuples::ignore, dependency), dependencies) { BOOST_FOREACH(tie(tuples::ignore, dependency), dependencies) {
Service::Ptr service = Service::GetByName(dependency); Service::Ptr service = Service::GetByName(dependency);
string parent = service->GetHost()->GetName(); String parent = service->GetHost()->GetName();
/* ignore ourselves */ /* ignore ourselves */
if (parent == GetName()) if (parent == GetName())
@ -84,17 +90,18 @@ set<string> Host::GetParents(void)
Dictionary::Ptr Host::GetMacros(void) const Dictionary::Ptr Host::GetMacros(void) const
{ {
Dictionary::Ptr value; Dictionary::Ptr value;
GetProperty("macros", &value); GetAttribute("macros", &value);
return value; return value;
} }
bool Host::IsReachable(void) bool Host::IsReachable(void)
{ {
Dictionary::Ptr dependencies; Dictionary::Ptr dependencies;
if (GetProperty("dependencies", &dependencies)) { GetAttribute("dependencies", &dependencies);
if (dependencies) {
dependencies = Service::ResolveDependencies(GetSelf(), dependencies); dependencies = Service::ResolveDependencies(GetSelf(), dependencies);
Variant dependency; Value dependency;
BOOST_FOREACH(tie(tuples::ignore, dependency), dependencies) { BOOST_FOREACH(tie(tuples::ignore, dependency), dependencies) {
Service::Ptr service = Service::GetByName(dependency); Service::Ptr service = Service::GetByName(dependency);
@ -111,10 +118,11 @@ bool Host::IsReachable(void)
bool Host::IsUp(void) bool Host::IsUp(void)
{ {
Dictionary::Ptr hostchecks; Dictionary::Ptr hostchecks;
if (GetProperty("hostchecks", &hostchecks)) { GetAttribute("hostchecks", &hostchecks);
if (hostchecks) {
hostchecks = Service::ResolveDependencies(GetSelf(), hostchecks); hostchecks = Service::ResolveDependencies(GetSelf(), hostchecks);
Variant hostcheck; Value hostcheck;
BOOST_FOREACH(tie(tuples::ignore, hostcheck), hostchecks) { BOOST_FOREACH(tie(tuples::ignore, hostcheck), hostchecks) {
Service::Ptr service = Service::GetByName(hostcheck); Service::Ptr service = Service::GetByName(hostcheck);

View File

@ -29,16 +29,14 @@ public:
typedef shared_ptr<Host> Ptr; typedef shared_ptr<Host> Ptr;
typedef weak_ptr<Host> WeakPtr; typedef weak_ptr<Host> WeakPtr;
Host(const Dictionary::Ptr& properties) Host(const Dictionary::Ptr& properties);
: DynamicObject(properties)
{ }
static bool Exists(const string& name); static bool Exists(const String& name);
static Host::Ptr GetByName(const string& name); static Host::Ptr GetByName(const String& name);
string GetAlias(void) const; String GetAlias(void) const;
Dictionary::Ptr GetGroups(void) const; Dictionary::Ptr GetGroups(void) const;
set<string> GetParents(void); set<String> GetParents(void);
Dictionary::Ptr GetMacros(void) const; Dictionary::Ptr GetMacros(void) const;
bool IsReachable(void); bool IsReachable(void);

View File

@ -23,36 +23,37 @@ using namespace icinga;
REGISTER_CLASS(HostGroup); REGISTER_CLASS(HostGroup);
string HostGroup::GetAlias(void) const String HostGroup::GetAlias(void) const
{ {
string value; String value;
GetAttribute("alias", &value);
if (GetProperty("alias", &value)) if (!value.IsEmpty())
return value; return value;
else
return GetName(); return GetName();
} }
string HostGroup::GetNotesUrl(void) const String HostGroup::GetNotesUrl(void) const
{ {
string value; String value;
GetProperty("notes_url", &value); GetAttribute("notes_url", &value);
return value; return value;
} }
string HostGroup::GetActionUrl(void) const String HostGroup::GetActionUrl(void) const
{ {
string value; String value;
GetProperty("action_url", &value); GetAttribute("action_url", &value);
return value; return value;
} }
bool HostGroup::Exists(const string& name) bool HostGroup::Exists(const String& name)
{ {
return (DynamicObject::GetObject("HostGroup", name)); return (DynamicObject::GetObject("HostGroup", name));
} }
HostGroup::Ptr HostGroup::GetByName(const string& name) HostGroup::Ptr HostGroup::GetByName(const String& name)
{ {
DynamicObject::Ptr configObject = DynamicObject::GetObject("HostGroup", name); DynamicObject::Ptr configObject = DynamicObject::GetObject("HostGroup", name);

View File

@ -33,12 +33,12 @@ public:
: DynamicObject(properties) : DynamicObject(properties)
{ } { }
static bool Exists(const string& name); static bool Exists(const String& name);
static HostGroup::Ptr GetByName(const string& name); static HostGroup::Ptr GetByName(const String& name);
string GetAlias(void) const; String GetAlias(void) const;
string GetNotesUrl(void) const; String GetNotesUrl(void) const;
string GetActionUrl(void) const; String GetActionUrl(void) const;
}; };
} }

View File

@ -21,36 +21,37 @@
using namespace icinga; using namespace icinga;
string MacroProcessor::ResolveMacros(const string& str, const vector<Dictionary::Ptr>& macroDicts) String MacroProcessor::ResolveMacros(const String& str, const vector<Dictionary::Ptr>& macroDicts)
{ {
string::size_type offset, pos_first, pos_second; size_t offset, pos_first, pos_second;
offset = 0; offset = 0;
string result = str; String result = str;
while ((pos_first = result.find_first_of('$', offset)) != string::npos) { while ((pos_first = result.FindFirstOf("$", offset)) != String::NPos) {
pos_second = result.find_first_of('$', pos_first + 1); pos_second = result.FindFirstOf("$", pos_first + 1);
if (pos_second == string::npos) if (pos_second == String::NPos)
throw_exception(runtime_error("Closing $ not found in macro format string.")); throw_exception(runtime_error("Closing $ not found in macro format String."));
string name = result.substr(pos_first + 1, pos_second - pos_first - 1); String name = result.SubStr(pos_first + 1, pos_second - pos_first - 1);
string value; String value;
bool resolved = false; bool resolved = false;
BOOST_FOREACH(const Dictionary::Ptr& macroDict, macroDicts) { BOOST_FOREACH(const Dictionary::Ptr& macroDict, macroDicts) {
if (macroDict && macroDict->Get(name, &value)) { if (!macroDict || !macroDict->Contains(name))
resolved = true; continue;
break;
} String value = macroDict->Get(name);
result.Replace(pos_first, pos_second - pos_first + 1, value);
offset = pos_first + value.GetLength();
resolved = true;
break;
} }
if (!resolved) if (!resolved)
throw_exception(runtime_error("Macro '" + name + "' is not defined.")); throw_exception(runtime_error("Macro '" + name + "' is not defined."));
result.replace(pos_first, pos_second - pos_first + 1, value);
offset = pos_first + value.size();
} }
return result; return result;

View File

@ -26,7 +26,7 @@ namespace icinga
class I2_CIB_API MacroProcessor class I2_CIB_API MacroProcessor
{ {
public: public:
static string ResolveMacros(const string& str, const vector<Dictionary::Ptr>& macroDicts); static String ResolveMacros(const String& str, const vector<Dictionary::Ptr>& macroDicts);
}; };
} }

View File

@ -25,30 +25,31 @@ NagiosCheckTask::NagiosCheckTask(const ScriptTask::Ptr& task, const Process::Ptr
: m_Task(task), m_Process(process) : m_Task(task), m_Process(process)
{ } { }
void NagiosCheckTask::ScriptFunc(const ScriptTask::Ptr& task, const vector<Variant>& arguments) void NagiosCheckTask::ScriptFunc(const ScriptTask::Ptr& task, const vector<Value>& arguments)
{ {
if (arguments.size() < 1) if (arguments.size() < 1)
throw_exception(invalid_argument("Missing argument: Service must be specified.")); throw_exception(invalid_argument("Missing argument: Service must be specified."));
Variant vservice = arguments[0]; Value vservice = arguments[0];
if (!vservice.IsObjectType<DynamicObject>()) if (!vservice.IsObjectType<DynamicObject>())
throw_exception(invalid_argument("Argument must be a config object.")); throw_exception(invalid_argument("Argument must be a config object."));
Service::Ptr service = static_cast<Service::Ptr>(vservice); Service::Ptr service = static_cast<Service::Ptr>(vservice);
string checkCommand = service->GetCheckCommand(); String checkCommand = service->GetCheckCommand();
vector<Dictionary::Ptr> macroDicts; vector<Dictionary::Ptr> macroDicts;
macroDicts.push_back(service->GetMacros()); macroDicts.push_back(service->GetMacros());
macroDicts.push_back(service->GetHost()->GetMacros()); macroDicts.push_back(service->GetHost()->GetMacros());
macroDicts.push_back(IcingaApplication::GetInstance()->GetMacros()); macroDicts.push_back(IcingaApplication::GetInstance()->GetMacros());
string command = MacroProcessor::ResolveMacros(checkCommand, macroDicts); String command = MacroProcessor::ResolveMacros(checkCommand, macroDicts);
Process::Ptr process = boost::make_shared<Process>(command); Process::Ptr process = boost::make_shared<Process>(command);
NagiosCheckTask ct(task, process); NagiosCheckTask ct(task, process);
ct.m_Result.SetScheduleStart(Utility::GetTime()); ct.m_Result = boost::make_shared<Dictionary>();
ct.m_Result->Set("schedule_start", Utility::GetTime());
process->Start(boost::bind(&NagiosCheckTask::ProcessFinishedHandler, ct)); process->Start(boost::bind(&NagiosCheckTask::ProcessFinishedHandler, ct));
} }
@ -64,11 +65,11 @@ void NagiosCheckTask::ProcessFinishedHandler(NagiosCheckTask ct)
return; return;
} }
ct.m_Result.SetExecutionStart(pr.ExecutionStart); ct.m_Result->Set("execution_start", pr.ExecutionStart);
ct.m_Result.SetExecutionEnd(pr.ExecutionEnd); ct.m_Result->Set("execution_end", pr.ExecutionEnd);
string output = pr.Output; String output = pr.Output;
boost::algorithm::trim(output); output.Trim();
ProcessCheckOutput(ct.m_Result, output); ProcessCheckOutput(ct.m_Result, output);
ServiceState state; ServiceState state;
@ -88,41 +89,40 @@ void NagiosCheckTask::ProcessFinishedHandler(NagiosCheckTask ct)
break; break;
} }
ct.m_Result.SetState(state); ct.m_Result->Set("state", state);
ct.m_Result.SetScheduleEnd(Utility::GetTime()); ct.m_Result->Set("schedule_end", Utility::GetTime());
ct.m_Task->FinishResult(ct.m_Result.GetDictionary()); ct.m_Task->FinishResult(ct.m_Result);
} }
void NagiosCheckTask::ProcessCheckOutput(CheckResult& result, const string& output) void NagiosCheckTask::ProcessCheckOutput(const Dictionary::Ptr& result, String& output)
{ {
string text; String text;
string perfdata; String perfdata;
vector<string> lines; vector<String> lines = output.Split(is_any_of("\r\n"));
boost::algorithm::split(lines, output, is_any_of("\r\n"));
BOOST_FOREACH (const string& line, lines) { BOOST_FOREACH (const String& line, lines) {
string::size_type delim = line.find('|'); size_t delim = line.FindFirstOf("|");
if (!text.empty()) if (!text.IsEmpty())
text.append("\n"); text += "\n";
if (delim != string::npos) { if (delim != String::NPos) {
text.append(line, 0, delim); text += line.SubStr(0, delim);
if (!perfdata.empty()) if (!perfdata.IsEmpty())
perfdata.append(" "); perfdata += " ";
perfdata.append(line, delim + 1, line.size()); perfdata += line.SubStr(delim + 1, line.GetLength());
} else { } else {
text.append(line); text += line;
} }
} }
result.SetOutput(text); result->Set("output", text);
result.SetPerformanceDataRaw(perfdata); result->Set("performance_data_raw", perfdata);
} }
void NagiosCheckTask::Register(void) void NagiosCheckTask::Register(void)

View File

@ -29,16 +29,16 @@ public:
static void Register(void); static void Register(void);
private: private:
static void ScriptFunc(const ScriptTask::Ptr& task, const vector<Variant>& arguments); static void ScriptFunc(const ScriptTask::Ptr& task, const vector<Value>& arguments);
static void ProcessFinishedHandler(NagiosCheckTask ct); static void ProcessFinishedHandler(NagiosCheckTask ct);
static void ProcessCheckOutput(CheckResult& result, const string& output); static void ProcessCheckOutput(const Dictionary::Ptr& result, String& output);
NagiosCheckTask(const ScriptTask::Ptr& task, const Process::Ptr& process); NagiosCheckTask(const ScriptTask::Ptr& task, const Process::Ptr& process);
ScriptTask::Ptr m_Task; ScriptTask::Ptr m_Task;
Process::Ptr m_Process; Process::Ptr m_Process;
CheckResult m_Result; Dictionary::Ptr m_Result;
}; };
} }

View File

@ -21,21 +21,21 @@
using namespace icinga; using namespace icinga;
void NullCheckTask::ScriptFunc(const ScriptTask::Ptr& task, const vector<Variant>& arguments) void NullCheckTask::ScriptFunc(const ScriptTask::Ptr& task, const vector<Value>& arguments)
{ {
if (arguments.size() < 1) if (arguments.size() < 1)
throw_exception(invalid_argument("Missing argument: Service must be specified.")); throw_exception(invalid_argument("Missing argument: Service must be specified."));
double now = Utility::GetTime(); double now = Utility::GetTime();
CheckResult cr; Dictionary::Ptr cr = boost::make_shared<Dictionary>();
cr.SetScheduleStart(now); cr->Set("schedule_start", now);
cr.SetScheduleEnd(now); cr->Set("schedule_end", now);
cr.SetExecutionStart(now); cr->Set("execution_start", now);
cr.SetExecutionEnd(now); cr->Set("execution_end", now);
cr.SetState(StateUnknown); cr->Set("state", StateUnknown);
task->FinishResult(cr.GetDictionary()); task->FinishResult(cr);
} }
void NullCheckTask::Register(void) void NullCheckTask::Register(void)

View File

@ -29,7 +29,7 @@ public:
static void Register(void); static void Register(void);
private: private:
static void ScriptFunc(const ScriptTask::Ptr& task, const vector<Variant>& arguments); static void ScriptFunc(const ScriptTask::Ptr& task, const vector<Value>& arguments);
}; };
} }

View File

@ -25,22 +25,47 @@ REGISTER_CLASS(Service);
boost::signal<void (const Service::Ptr&, const CheckResultMessage&)> Service::OnCheckResultReceived; boost::signal<void (const Service::Ptr&, const CheckResultMessage&)> Service::OnCheckResultReceived;
string Service::GetAlias(void) const Service::Service(const Dictionary::Ptr& serializedObject)
: DynamicObject(serializedObject)
{ {
string value; RegisterAttribute("alias", Attribute_Config);
RegisterAttribute("host_name", Attribute_Config);
RegisterAttribute("macros", Attribute_Config);
RegisterAttribute("check_command", Attribute_Config);
RegisterAttribute("max_check_attempts", Attribute_Config);
RegisterAttribute("check_interval", Attribute_Config);
RegisterAttribute("retry_interval", Attribute_Config);
RegisterAttribute("dependencies", Attribute_Config);
RegisterAttribute("servicegroups", Attribute_Config);
RegisterAttribute("checkers", Attribute_Config);
if (GetProperty("alias", &value)) RegisterAttribute("scheduling_offset", Attribute_Transient);
RegisterAttribute("next_check", Attribute_Replicated);
RegisterAttribute("checker", Attribute_Replicated);
RegisterAttribute("check_attempt", Attribute_Replicated);
RegisterAttribute("state", Attribute_Replicated);
RegisterAttribute("state_type", Attribute_Replicated);
RegisterAttribute("last_result", Attribute_Replicated);
RegisterAttribute("last_state_change", Attribute_Replicated);
RegisterAttribute("last_hard_state_change", Attribute_Replicated);
}
String Service::GetAlias(void) const
{
String value;
if (GetAttribute("alias", &value))
return value; return value;
return GetName(); return GetName();
} }
bool Service::Exists(const string& name) bool Service::Exists(const String& name)
{ {
return (DynamicObject::GetObject("Service", name)); return (DynamicObject::GetObject("Service", name));
} }
Service::Ptr Service::GetByName(const string& name) Service::Ptr Service::GetByName(const String& name)
{ {
DynamicObject::Ptr configObject = DynamicObject::GetObject("Service", name); DynamicObject::Ptr configObject = DynamicObject::GetObject("Service", name);
@ -52,8 +77,8 @@ Service::Ptr Service::GetByName(const string& name)
Host::Ptr Service::GetHost(void) const Host::Ptr Service::GetHost(void) const
{ {
string hostname; String hostname;
if (!GetProperty("host_name", &hostname)) if (!GetAttribute("host_name", &hostname))
throw_exception(runtime_error("Service object is missing the 'host_name' property.")); throw_exception(runtime_error("Service object is missing the 'host_name' property."));
return Host::GetByName(hostname); return Host::GetByName(hostname);
@ -62,28 +87,28 @@ Host::Ptr Service::GetHost(void) const
Dictionary::Ptr Service::GetMacros(void) const Dictionary::Ptr Service::GetMacros(void) const
{ {
Dictionary::Ptr macros; Dictionary::Ptr macros;
GetProperty("macros", &macros); GetAttribute("macros", &macros);
return macros; return macros;
} }
string Service::GetCheckCommand(void) const String Service::GetCheckCommand(void) const
{ {
string value; String value;
GetProperty("check_command", &value); GetAttribute("check_command", &value);
return value; return value;
} }
long Service::GetMaxCheckAttempts(void) const long Service::GetMaxCheckAttempts(void) const
{ {
long value = 3; long value = 3;
GetProperty("max_check_attempts", &value); GetAttribute("max_check_attempts", &value);
return value; return value;
} }
long Service::GetCheckInterval(void) const long Service::GetCheckInterval(void) const
{ {
long value = 300; long value = 300;
GetProperty("check_interval", &value); GetAttribute("check_interval", &value);
if (value < 15) if (value < 15)
value = 15; value = 15;
@ -94,7 +119,7 @@ long Service::GetCheckInterval(void) const
long Service::GetRetryInterval(void) const long Service::GetRetryInterval(void) const
{ {
long value; long value;
if (!GetProperty("retry_interval", &value)) if (!GetAttribute("retry_interval", &value))
value = GetCheckInterval() / 5; value = GetCheckInterval() / 5;
return value; return value;
@ -103,7 +128,7 @@ long Service::GetRetryInterval(void) const
Dictionary::Ptr Service::GetDependencies(void) const Dictionary::Ptr Service::GetDependencies(void) const
{ {
Dictionary::Ptr value; Dictionary::Ptr value;
GetProperty("dependencies", &value); GetAttribute("dependencies", &value);
return value; return value;
} }
@ -115,7 +140,7 @@ void Service::GetDependenciesRecursive(const Dictionary::Ptr& result) const {
if (!dependencies) if (!dependencies)
return; return;
Variant dependency; Value dependency;
BOOST_FOREACH(tie(tuples::ignore, dependency), dependencies) { BOOST_FOREACH(tie(tuples::ignore, dependency), dependencies) {
if (result->Contains(dependency)) if (result->Contains(dependency))
continue; continue;
@ -130,14 +155,14 @@ void Service::GetDependenciesRecursive(const Dictionary::Ptr& result) const {
Dictionary::Ptr Service::GetGroups(void) const Dictionary::Ptr Service::GetGroups(void) const
{ {
Dictionary::Ptr value; Dictionary::Ptr value;
GetProperty("servicegroups", &value); GetAttribute("servicegroups", &value);
return value; return value;
} }
Dictionary::Ptr Service::GetCheckers(void) const Dictionary::Ptr Service::GetCheckers(void) const
{ {
Dictionary::Ptr value; Dictionary::Ptr value;
GetProperty("checkers", &value); GetAttribute("checkers", &value);
return value; return value;
} }
@ -146,7 +171,7 @@ bool Service::IsReachable(void) const
Dictionary::Ptr dependencies = boost::make_shared<Dictionary>(); Dictionary::Ptr dependencies = boost::make_shared<Dictionary>();
GetDependenciesRecursive(dependencies); GetDependenciesRecursive(dependencies);
Variant dependency; Value dependency;
BOOST_FOREACH(tie(tuples::ignore, dependency), dependencies) { BOOST_FOREACH(tie(tuples::ignore, dependency), dependencies) {
Service::Ptr service = Service::GetByName(dependency); Service::Ptr service = Service::GetByName(dependency);
@ -155,7 +180,7 @@ bool Service::IsReachable(void) const
continue; continue;
/* ignore pending services */ /* ignore pending services */
if (!service->HasLastCheckResult()) if (!service->GetLastCheckResult())
continue; continue;
/* ignore soft states */ /* ignore soft states */
@ -175,13 +200,13 @@ bool Service::IsReachable(void) const
void Service::SetSchedulingOffset(long offset) void Service::SetSchedulingOffset(long offset)
{ {
SetTag("scheduling_offset", offset); SetAttribute("scheduling_offset", offset);
} }
long Service::GetSchedulingOffset(void) long Service::GetSchedulingOffset(void)
{ {
long value; long value;
if (!GetTag("scheduling_offset", &value)) { if (!GetAttribute("scheduling_offset", &value)) {
value = rand(); value = rand();
SetSchedulingOffset(value); SetSchedulingOffset(value);
} }
@ -190,15 +215,17 @@ long Service::GetSchedulingOffset(void)
void Service::SetNextCheck(double nextCheck) void Service::SetNextCheck(double nextCheck)
{ {
SetTag("next_check", nextCheck); SetAttribute("next_check", nextCheck);
} }
double Service::GetNextCheck(void) double Service::GetNextCheck(void)
{ {
double value; double value;
if (!GetTag("next_check", &value)) { if (!GetAttribute("next_check", &value)) {
UpdateNextCheck(); UpdateNextCheck();
return GetNextCheck();
if (!GetAttribute("next_check", &value))
throw_exception(runtime_error("Failed to schedule next check."));
} }
return value; return value;
} }
@ -217,107 +244,100 @@ void Service::UpdateNextCheck(void)
SetNextCheck(now - adj + interval); SetNextCheck(now - adj + interval);
} }
void Service::SetChecker(const string& checker) void Service::SetChecker(const String& checker)
{ {
SetTag("checker", checker); SetAttribute("checker", checker);
} }
string Service::GetChecker(void) const String Service::GetChecker(void) const
{ {
string value; String value;
GetTag("checker", &value); GetAttribute("checker", &value);
return value; return value;
} }
void Service::SetCurrentCheckAttempt(long attempt) void Service::SetCurrentCheckAttempt(long attempt)
{ {
SetTag("check_attempt", attempt); SetAttribute("check_attempt", attempt);
} }
long Service::GetCurrentCheckAttempt(void) const long Service::GetCurrentCheckAttempt(void) const
{ {
long value = 1; long value = 1;
GetTag("check_attempt", &value); GetAttribute("check_attempt", &value);
return value; return value;
} }
void Service::SetState(ServiceState state) void Service::SetState(ServiceState state)
{ {
SetTag("state", static_cast<long>(state)); SetAttribute("state", static_cast<long>(state));
} }
ServiceState Service::GetState(void) const ServiceState Service::GetState(void) const
{ {
long value = StateUnknown; long value = StateUnknown;
GetTag("state", &value); GetAttribute("state", &value);
return static_cast<ServiceState>(value); return static_cast<ServiceState>(value);
} }
void Service::SetStateType(ServiceStateType type) void Service::SetStateType(ServiceStateType type)
{ {
SetTag("state_type", static_cast<long>(type)); SetAttribute("state_type", static_cast<long>(type));
} }
ServiceStateType Service::GetStateType(void) const ServiceStateType Service::GetStateType(void) const
{ {
long value = StateTypeHard; long value = StateTypeHard;
GetTag("state_type", &value); GetAttribute("state_type", &value);
return static_cast<ServiceStateType>(value); return static_cast<ServiceStateType>(value);
} }
void Service::SetLastCheckResult(const CheckResult& result) void Service::SetLastCheckResult(const Dictionary::Ptr& result)
{ {
SetTag("last_result", result.GetDictionary()); SetAttribute("last_result", result);
} }
bool Service::HasLastCheckResult(void) const Dictionary::Ptr Service::GetLastCheckResult(void) const
{ {
Dictionary::Ptr value; Dictionary::Ptr value;
return GetTag("last_result", &value) && value; GetAttribute("last_result", &value);
} return value;
CheckResult Service::GetLastCheckResult(void) const
{
Dictionary::Ptr value;
if (!GetTag("last_result", &value))
throw_exception(invalid_argument("Service has no last check result."));
return CheckResult(value);
} }
void Service::SetLastStateChange(double ts) void Service::SetLastStateChange(double ts)
{ {
SetTag("last_state_change", static_cast<long>(ts)); SetAttribute("last_state_change", static_cast<long>(ts));
} }
double Service::GetLastStateChange(void) const double Service::GetLastStateChange(void) const
{ {
long value; long value;
if (!GetTag("last_state_change", &value)) if (!GetAttribute("last_state_change", &value))
value = IcingaApplication::GetInstance()->GetStartTime(); value = IcingaApplication::GetInstance()->GetStartTime();
return value; return value;
} }
void Service::SetLastHardStateChange(double ts) void Service::SetLastHardStateChange(double ts)
{ {
SetTag("last_hard_state_change", ts); SetAttribute("last_hard_state_change", ts);
} }
double Service::GetLastHardStateChange(void) const double Service::GetLastHardStateChange(void) const
{ {
double value; double value;
if (!GetTag("last_hard_state_change", &value)) if (!GetAttribute("last_hard_state_change", &value))
value = IcingaApplication::GetInstance()->GetStartTime(); value = IcingaApplication::GetInstance()->GetStartTime();
return value; return value;
} }
void Service::ApplyCheckResult(const CheckResult& cr) void Service::ApplyCheckResult(const Dictionary::Ptr& cr)
{ {
ServiceState old_state = GetState(); ServiceState old_state = GetState();
ServiceStateType old_stateType = GetStateType(); ServiceStateType old_stateType = GetStateType();
long attempt = GetCurrentCheckAttempt(); long attempt = GetCurrentCheckAttempt();
if (cr.GetState() == StateOK) { if (cr->Get("state") == StateOK) {
if (GetState() == StateOK) if (GetState() == StateOK)
SetStateType(StateTypeHard); SetStateType(StateTypeHard);
@ -333,7 +353,9 @@ void Service::ApplyCheckResult(const CheckResult& cr)
} }
SetCurrentCheckAttempt(attempt); SetCurrentCheckAttempt(attempt);
SetState(cr.GetState());
int state = cr->Get("state");
SetState(static_cast<ServiceState>(state));
SetLastCheckResult(cr); SetLastCheckResult(cr);
@ -345,14 +367,12 @@ void Service::ApplyCheckResult(const CheckResult& cr)
if (old_stateType != GetStateType()) if (old_stateType != GetStateType())
SetLastHardStateChange(now); SetLastHardStateChange(now);
} }
UpdateNextCheck();
} }
ServiceState Service::StateFromString(const string& state) ServiceState Service::StateFromString(const String& state)
{ {
/* TODO: make this thread-safe */ /* TODO: make this thread-safe */
static map<string, ServiceState> stateLookup; static map<String, ServiceState> stateLookup;
if (stateLookup.empty()) { if (stateLookup.empty()) {
stateLookup["ok"] = StateOK; stateLookup["ok"] = StateOK;
@ -362,7 +382,7 @@ ServiceState Service::StateFromString(const string& state)
stateLookup["unknown"] = StateUnknown; stateLookup["unknown"] = StateUnknown;
} }
map<string, ServiceState>::iterator it; map<String, ServiceState>::iterator it;
it = stateLookup.find(state); it = stateLookup.find(state);
if (it == stateLookup.end()) if (it == stateLookup.end())
@ -371,7 +391,7 @@ ServiceState Service::StateFromString(const string& state)
return it->second; return it->second;
} }
string Service::StateToString(ServiceState state) String Service::StateToString(ServiceState state)
{ {
switch (state) { switch (state) {
case StateOK: case StateOK:
@ -388,7 +408,7 @@ string Service::StateToString(ServiceState state)
} }
} }
ServiceStateType Service::StateTypeFromString(const string& type) ServiceStateType Service::StateTypeFromString(const String& type)
{ {
if (type == "soft") if (type == "soft")
return StateTypeSoft; return StateTypeSoft;
@ -396,7 +416,7 @@ ServiceStateType Service::StateTypeFromString(const string& type)
return StateTypeHard; return StateTypeHard;
} }
string Service::StateTypeToString(ServiceStateType type) String Service::StateTypeToString(ServiceStateType type)
{ {
if (type == StateTypeSoft) if (type == StateTypeSoft)
return "soft"; return "soft";
@ -404,14 +424,14 @@ string Service::StateTypeToString(ServiceStateType type)
return "hard"; return "hard";
} }
bool Service::IsAllowedChecker(const string& checker) const bool Service::IsAllowedChecker(const String& checker) const
{ {
Dictionary::Ptr checkers = GetCheckers(); Dictionary::Ptr checkers = GetCheckers();
if (!checkers) if (!checkers)
return true; return true;
Variant pattern; Value pattern;
BOOST_FOREACH(tie(tuples::ignore, pattern), checkers) { BOOST_FOREACH(tie(tuples::ignore, pattern), checkers) {
if (Utility::Match(pattern, checker)) if (Utility::Match(pattern, checker))
return true; return true;
@ -423,18 +443,18 @@ bool Service::IsAllowedChecker(const string& checker) const
Dictionary::Ptr Service::ResolveDependencies(const Host::Ptr& host, const Dictionary::Ptr& dependencies) Dictionary::Ptr Service::ResolveDependencies(const Host::Ptr& host, const Dictionary::Ptr& dependencies)
{ {
Dictionary::Ptr services; Dictionary::Ptr services;
host->GetProperty("services", &services); host->GetAttribute("services", &services);
Dictionary::Ptr result = boost::make_shared<Dictionary>(); Dictionary::Ptr result = boost::make_shared<Dictionary>();
Variant dependency; Value dependency;
BOOST_FOREACH(tie(tuples::ignore, dependency), dependencies) { BOOST_FOREACH(tie(tuples::ignore, dependency), dependencies) {
string name; String name;
if (services && services->Contains(dependency)) if (services && services->Contains(dependency))
name = host->GetName() + "-" + static_cast<string>(dependency); name = host->GetName() + "-" + static_cast<String>(dependency);
else else
name = static_cast<string>(dependency); name = static_cast<String>(dependency);
result->Set(name, name); result->Set(name, name);
} }

View File

@ -38,7 +38,6 @@ enum ServiceStateType
StateTypeHard StateTypeHard
}; };
class CheckResult;
class CheckResultMessage; class CheckResultMessage;
class ServiceStatusMessage; class ServiceStatusMessage;
@ -48,17 +47,15 @@ public:
typedef shared_ptr<Service> Ptr; typedef shared_ptr<Service> Ptr;
typedef weak_ptr<Service> WeakPtr; typedef weak_ptr<Service> WeakPtr;
Service(const Dictionary::Ptr& properties) Service(const Dictionary::Ptr& properties);
: DynamicObject(properties)
{ }
static bool Exists(const string& name); static bool Exists(const String& name);
static Service::Ptr GetByName(const string& name); static Service::Ptr GetByName(const String& name);
string GetAlias(void) const; String GetAlias(void) const;
Host::Ptr GetHost(void) const; Host::Ptr GetHost(void) const;
Dictionary::Ptr GetMacros(void) const; Dictionary::Ptr GetMacros(void) const;
string GetCheckCommand(void) const; String GetCheckCommand(void) const;
long GetMaxCheckAttempts(void) const; long GetMaxCheckAttempts(void) const;
long GetCheckInterval(void) const; long GetCheckInterval(void) const;
long GetRetryInterval(void) const; long GetRetryInterval(void) const;
@ -76,10 +73,10 @@ public:
double GetNextCheck(void); double GetNextCheck(void);
void UpdateNextCheck(void); void UpdateNextCheck(void);
void SetChecker(const string& checker); void SetChecker(const String& checker);
string GetChecker(void) const; String GetChecker(void) const;
bool IsAllowedChecker(const string& checker) const; bool IsAllowedChecker(const String& checker) const;
void SetCurrentCheckAttempt(long attempt); void SetCurrentCheckAttempt(long attempt);
long GetCurrentCheckAttempt(void) const; long GetCurrentCheckAttempt(void) const;
@ -90,9 +87,8 @@ public:
void SetStateType(ServiceStateType type); void SetStateType(ServiceStateType type);
ServiceStateType GetStateType(void) const; ServiceStateType GetStateType(void) const;
bool HasLastCheckResult(void) const; void SetLastCheckResult(const Dictionary::Ptr& result);
void SetLastCheckResult(const CheckResult& result); Dictionary::Ptr GetLastCheckResult(void) const;
CheckResult GetLastCheckResult(void) const;
void SetLastStateChange(double ts); void SetLastStateChange(double ts);
double GetLastStateChange(void) const; double GetLastStateChange(void) const;
@ -100,13 +96,13 @@ public:
void SetLastHardStateChange(double ts); void SetLastHardStateChange(double ts);
double GetLastHardStateChange(void) const; double GetLastHardStateChange(void) const;
void ApplyCheckResult(const CheckResult& cr); void ApplyCheckResult(const Dictionary::Ptr& cr);
static ServiceState StateFromString(const string& state); static ServiceState StateFromString(const String& state);
static string StateToString(ServiceState state); static String StateToString(ServiceState state);
static ServiceStateType StateTypeFromString(const string& state); static ServiceStateType StateTypeFromString(const String& state);
static string StateTypeToString(ServiceStateType state); static String StateTypeToString(ServiceStateType state);
static Dictionary::Ptr ResolveDependencies(const Host::Ptr& host, const Dictionary::Ptr& dependencies); static Dictionary::Ptr ResolveDependencies(const Host::Ptr& host, const Dictionary::Ptr& dependencies);

View File

@ -23,36 +23,37 @@ using namespace icinga;
REGISTER_CLASS(ServiceGroup); REGISTER_CLASS(ServiceGroup);
string ServiceGroup::GetAlias(void) const String ServiceGroup::GetAlias(void) const
{ {
string value; String value;
GetAttribute("alias", &value);
if (GetProperty("alias", &value)) if (!value.IsEmpty())
return value; return value;
else
return GetName(); return GetName();
} }
string ServiceGroup::GetNotesUrl(void) const String ServiceGroup::GetNotesUrl(void) const
{ {
string value; String value;
GetProperty("notes_url", &value); GetAttribute("notes_url", &value);
return value; return value;
} }
string ServiceGroup::GetActionUrl(void) const String ServiceGroup::GetActionUrl(void) const
{ {
string value; String value;
GetProperty("action_url", &value); GetAttribute("action_url", &value);
return value; return value;
} }
bool ServiceGroup::Exists(const string& name) bool ServiceGroup::Exists(const String& name)
{ {
return (DynamicObject::GetObject("ServiceGroup", name)); return (DynamicObject::GetObject("ServiceGroup", name));
} }
ServiceGroup::Ptr ServiceGroup::GetByName(const string& name) ServiceGroup::Ptr ServiceGroup::GetByName(const String& name)
{ {
DynamicObject::Ptr configObject = DynamicObject::GetObject("ServiceGroup", name); DynamicObject::Ptr configObject = DynamicObject::GetObject("ServiceGroup", name);

View File

@ -33,12 +33,12 @@ public:
: DynamicObject(properties) : DynamicObject(properties)
{ } { }
static bool Exists(const string& name); static bool Exists(const String& name);
static ServiceGroup::Ptr GetByName(const string& name); static ServiceGroup::Ptr GetByName(const String& name);
string GetAlias(void) const; String GetAlias(void) const;
string GetNotesUrl(void) const; String GetNotesUrl(void) const;
string GetActionUrl(void) const; String GetActionUrl(void) const;
}; };
} }

View File

@ -72,13 +72,13 @@ void CheckerComponent::CheckTimerHandler(void)
m_PendingServices.insert(service); m_PendingServices.insert(service);
vector<Variant> arguments; vector<Value> arguments;
arguments.push_back(service); arguments.push_back(service);
ScriptTask::Ptr task; ScriptTask::Ptr task;
task = service->InvokeMethod("check", arguments, boost::bind(&CheckerComponent::CheckCompletedHandler, this, service, _1)); task = service->InvokeMethod("check", arguments, boost::bind(&CheckerComponent::CheckCompletedHandler, this, service, _1));
assert(task); /* TODO: gracefully handle missing methods */ assert(task); /* TODO: gracefully handle missing methods */
service->SetTag("current_task", task); service->SetAttribute("current_task", task);
tasks++; tasks++;
} }
@ -92,20 +92,22 @@ void CheckerComponent::CheckTimerHandler(void)
void CheckerComponent::CheckCompletedHandler(const Service::Ptr& service, const ScriptTask::Ptr& task) void CheckerComponent::CheckCompletedHandler(const Service::Ptr& service, const ScriptTask::Ptr& task)
{ {
service->RemoveTag("current_task"); service->ClearAttribute("current_task");
try { try {
Variant vresult = task->GetResult(); Value vresult = task->GetResult();
if (vresult.IsObjectType<Dictionary>()) { if (vresult.IsObjectType<Dictionary>()) {
CheckResult result = CheckResult(static_cast<Dictionary::Ptr>(vresult)); Dictionary::Ptr result = vresult;
service->ApplyCheckResult(result);
RequestMessage rm; RequestMessage rm;
rm.SetMethod("checker::CheckResult"); rm.SetMethod("checker::ServiceStateChange");
/* TODO: add _old_ state to message */
CheckResultMessage params; CheckResultMessage params;
params.SetService(service->GetName()); params.SetService(service->GetName());
params.SetCheckResult(result);
rm.SetParams(params); rm.SetParams(params);
@ -118,11 +120,13 @@ void CheckerComponent::CheckCompletedHandler(const Service::Ptr& service, const
Logger::Write(LogWarning, "checker", msgbuf.str()); Logger::Write(LogWarning, "checker", msgbuf.str());
} }
/* figure out when the next check is for this service; the local /* figure out when the next check is for this service; the call to
* cibsync component should've already done this as part of processing * ApplyCheckResult() should've already done this but lets do it again
* the CheckResult message, but lets do it again to be sure */ * just in case there was no check result. */
service->UpdateNextCheck(); service->UpdateNextCheck();
assert(service->GetNextCheck() > Utility::GetTime());
/* remove the service from the list of pending services; if it's not in the /* remove the service from the list of pending services; if it's not in the
* list this was a manual (i.e. forced) check and we must not re-add the * list this was a manual (i.e. forced) check and we must not re-add the
* service to the services list because it's already there. */ * service to the services list because it's already there. */
@ -151,7 +155,7 @@ void CheckerComponent::AssignServiceRequestHandler(const Endpoint::Ptr& sender,
if (!request.GetParams(&params)) if (!request.GetParams(&params))
return; return;
string service; String service;
if (!params.Get("service", &service)) if (!params.Get("service", &service))
return; return;

View File

@ -34,17 +34,18 @@ void CIBSyncComponent::Start(void)
m_Endpoint->RegisterTopicHandler("config::FetchObjects", m_Endpoint->RegisterTopicHandler("config::FetchObjects",
boost::bind(&CIBSyncComponent::FetchObjectsHandler, this, _2)); boost::bind(&CIBSyncComponent::FetchObjectsHandler, this, _2));
DynamicObject::OnCommitted.connect(boost::bind(&CIBSyncComponent::LocalObjectCommittedHandler, this, _1)); DynamicObject::OnRegistered.connect(boost::bind(&CIBSyncComponent::LocalObjectRegisteredHandler, this, _1));
DynamicObject::OnRemoved.connect(boost::bind(&CIBSyncComponent::LocalObjectRemovedHandler, this, _1)); DynamicObject::OnUnregistered.connect(boost::bind(&CIBSyncComponent::LocalObjectUnregisteredHandler, this, _1));
DynamicObject::OnTransactionClosing.connect(boost::bind(&CIBSyncComponent::TransactionClosingHandler, this, _1));
m_Endpoint->RegisterPublication("config::ObjectCommitted"); m_Endpoint->RegisterPublication("config::ObjectUpdate");
m_Endpoint->RegisterPublication("config::ObjectRemoved"); m_Endpoint->RegisterPublication("config::ObjectRemoved");
EndpointManager::GetInstance()->OnNewEndpoint.connect(boost::bind(&CIBSyncComponent::NewEndpointHandler, this, _2)); EndpointManager::GetInstance()->OnNewEndpoint.connect(boost::bind(&CIBSyncComponent::NewEndpointHandler, this, _2));
m_Endpoint->RegisterPublication("config::FetchObjects"); m_Endpoint->RegisterPublication("config::FetchObjects");
m_Endpoint->RegisterTopicHandler("config::ObjectCommitted", m_Endpoint->RegisterTopicHandler("config::ObjectUpdate",
boost::bind(&CIBSyncComponent::RemoteObjectCommittedHandler, this, _2, _3)); boost::bind(&CIBSyncComponent::RemoteObjectUpdateHandler, this, _2, _3));
m_Endpoint->RegisterTopicHandler("config::ObjectRemoved", m_Endpoint->RegisterTopicHandler("config::ObjectRemoved",
boost::bind(&CIBSyncComponent::RemoteObjectRemovedHandler, this, _3)); boost::bind(&CIBSyncComponent::RemoteObjectRemovedHandler, this, _3));
@ -72,18 +73,18 @@ void CIBSyncComponent::CheckResultRequestHandler(const Endpoint::Ptr& sender, co
if (!request.GetParams(&params)) if (!request.GetParams(&params))
return; return;
string svcname; String svcname;
if (!params.GetService(&svcname)) if (!params.GetService(&svcname))
return; return;
Service::Ptr service = Service::GetByName(svcname); Service::Ptr service = Service::GetByName(svcname);
CheckResult cr; //CheckResult cr;
if (!params.GetCheckResult(&cr)) //if (!params.GetCheckResult(&cr))
return; // return;
Service::OnCheckResultReceived(service, params); //Service::OnCheckResultReceived(service, params);
service->ApplyCheckResult(cr); //service->ApplyCheckResult(cr);
time_t now = Utility::GetTime(); time_t now = Utility::GetTime();
CIB::UpdateTaskStatistics(now, 1); CIB::UpdateTaskStatistics(now, 1);
@ -106,7 +107,7 @@ void CIBSyncComponent::SessionEstablishedHandler(const Endpoint::Ptr& endpoint)
EndpointManager::GetInstance()->SendUnicastMessage(m_Endpoint, endpoint, request); EndpointManager::GetInstance()->SendUnicastMessage(m_Endpoint, endpoint, request);
} }
RequestMessage CIBSyncComponent::MakeObjectMessage(const DynamicObject::Ptr& object, string method, bool includeProperties) RequestMessage CIBSyncComponent::MakeObjectMessage(const DynamicObject::Ptr& object, const String& method, double sinceTx, bool includeProperties)
{ {
RequestMessage msg; RequestMessage msg;
msg.SetMethod(method); msg.SetMethod(method);
@ -118,7 +119,7 @@ RequestMessage CIBSyncComponent::MakeObjectMessage(const DynamicObject::Ptr& obj
params.Set("type", object->GetType()); params.Set("type", object->GetType());
if (includeProperties) if (includeProperties)
params.Set("properties", object->GetProperties()); params.Set("update", object->BuildUpdate(sinceTx, Attribute_Replicated | Attribute_Config));
return msg; return msg;
} }
@ -138,14 +139,14 @@ void CIBSyncComponent::FetchObjectsHandler(const Endpoint::Ptr& sender)
if (!ShouldReplicateObject(object)) if (!ShouldReplicateObject(object))
continue; continue;
RequestMessage request = MakeObjectMessage(object, "config::ObjectCommitted", true); RequestMessage request = MakeObjectMessage(object, "config::ObjectUpdate", 0, true);
EndpointManager::GetInstance()->SendUnicastMessage(m_Endpoint, sender, request); EndpointManager::GetInstance()->SendUnicastMessage(m_Endpoint, sender, request);
} }
} }
} }
void CIBSyncComponent::LocalObjectCommittedHandler(const DynamicObject::Ptr& object) void CIBSyncComponent::LocalObjectRegisteredHandler(const DynamicObject::Ptr& object)
{ {
/* don't send messages when we're currently processing a remote update */ /* don't send messages when we're currently processing a remote update */
if (m_SyncingConfig) if (m_SyncingConfig)
@ -155,10 +156,10 @@ void CIBSyncComponent::LocalObjectCommittedHandler(const DynamicObject::Ptr& obj
return; return;
EndpointManager::GetInstance()->SendMulticastMessage(m_Endpoint, EndpointManager::GetInstance()->SendMulticastMessage(m_Endpoint,
MakeObjectMessage(object, "config::ObjectCommitted", true)); MakeObjectMessage(object, "config::ObjectCommitted", 0, true));
} }
void CIBSyncComponent::LocalObjectRemovedHandler(const DynamicObject::Ptr& object) void CIBSyncComponent::LocalObjectUnregisteredHandler(const DynamicObject::Ptr& object)
{ {
/* don't send messages when we're currently processing a remote update */ /* don't send messages when we're currently processing a remote update */
if (m_SyncingConfig) if (m_SyncingConfig)
@ -168,66 +169,65 @@ void CIBSyncComponent::LocalObjectRemovedHandler(const DynamicObject::Ptr& objec
return; return;
EndpointManager::GetInstance()->SendMulticastMessage(m_Endpoint, EndpointManager::GetInstance()->SendMulticastMessage(m_Endpoint,
MakeObjectMessage(object, "config::ObjectRemoved", false)); MakeObjectMessage(object, "config::ObjectRemoved", 0, false));
} }
void CIBSyncComponent::RemoteObjectCommittedHandler(const Endpoint::Ptr& sender, const RequestMessage& request) void CIBSyncComponent::TransactionClosingHandler(const set<DynamicObject::Ptr>& modifiedObjects)
{
stringstream msgbuf;
msgbuf << "Sending " << modifiedObjects.size() << " replication updates.";
Logger::Write(LogInformation, "cibsync", msgbuf.str());
BOOST_FOREACH(const DynamicObject::Ptr& object, modifiedObjects) {
if (!ShouldReplicateObject(object))
continue;
RequestMessage request = MakeObjectMessage(object, "config::ObjectUpdate", DynamicObject::GetCurrentTx(), true);
EndpointManager::GetInstance()->SendMulticastMessage(m_Endpoint, request);
}
}
void CIBSyncComponent::RemoteObjectUpdateHandler(const Endpoint::Ptr& sender, const RequestMessage& request)
{ {
MessagePart params; MessagePart params;
if (!request.GetParams(&params)) if (!request.GetParams(&params))
return; return;
string name; String name;
if (!params.Get("name", &name)) if (!params.Get("name", &name))
return; return;
string type; String type;
if (!params.Get("type", &type)) if (!params.Get("type", &type))
return; return;
MessagePart properties; Dictionary::Ptr update;
if (!params.Get("properties", &properties)) if (!params.Get("update", &update))
return; return;
DynamicObject::Ptr object = DynamicObject::GetObject(type, name); DynamicObject::Ptr object = DynamicObject::GetObject(type, name);
if (!object) { if (!object) {
object = boost::make_shared<DynamicObject>(properties.GetDictionary()); object = DynamicObject::Create(type, update);
if (object->GetSource() == EndpointManager::GetInstance()->GetIdentity()) { if (object->GetSource() == EndpointManager::GetInstance()->GetIdentity()) {
/* the peer sent us an object that was originally created by us - /* the peer sent us an object that was originally created by us -
* however if was deleted locally so we have to tell the peer to destroy * however it was deleted locally so we have to tell the peer to destroy
* its copy of the object. */ * its copy of the object. */
EndpointManager::GetInstance()->SendMulticastMessage(m_Endpoint, EndpointManager::GetInstance()->SendMulticastMessage(m_Endpoint,
MakeObjectMessage(object, "config::ObjectRemoved", false)); MakeObjectMessage(object, "config::ObjectRemoved", 0, false));
return; return;
} }
} else { } else {
DynamicObject::Ptr remoteObject = boost::make_shared<DynamicObject>(properties.GetDictionary()); if (object->IsLocal())
throw_exception(invalid_argument("Replicated remote object is marked as local."));
if (object->GetCommitTimestamp() >= remoteObject->GetCommitTimestamp()) if (object->GetSource().IsEmpty())
return; object->SetSource(sender->GetIdentity());
object->SetProperties(properties.GetDictionary()); object->ApplyUpdate(update, true);
}
if (object->IsLocal())
throw_exception(invalid_argument("Replicated remote object is marked as local."));
if (object->GetSource().empty())
object->SetSource(sender->GetIdentity());
try {
/* TODO: only ignore updates for _this_ object rather than all objects
* this might be relevant if the commit handler for this object
* creates other objects. */
m_SyncingConfig = true;
object->Commit();
m_SyncingConfig = false;
} catch (...) {
m_SyncingConfig = false;
throw;
} }
} }
@ -237,11 +237,11 @@ void CIBSyncComponent::RemoteObjectRemovedHandler(const RequestMessage& request)
if (!request.GetParams(&params)) if (!request.GetParams(&params))
return; return;
string name; String name;
if (!params.Get("name", &name)) if (!params.Get("name", &name))
return; return;
string type; String type;
if (!params.Get("type", &type)) if (!params.Get("type", &type))
return; return;

View File

@ -41,15 +41,16 @@ private:
void NewEndpointHandler(const Endpoint::Ptr& endpoint); void NewEndpointHandler(const Endpoint::Ptr& endpoint);
void SessionEstablishedHandler(const Endpoint::Ptr& endpoint); void SessionEstablishedHandler(const Endpoint::Ptr& endpoint);
void LocalObjectCommittedHandler(const DynamicObject::Ptr& object); void LocalObjectRegisteredHandler(const DynamicObject::Ptr& object);
void LocalObjectRemovedHandler(const DynamicObject::Ptr& object); void LocalObjectUnregisteredHandler(const DynamicObject::Ptr& object);
void TransactionClosingHandler(const set<DynamicObject::Ptr>& modifiedObjects);
void FetchObjectsHandler(const Endpoint::Ptr& sender); void FetchObjectsHandler(const Endpoint::Ptr& sender);
void RemoteObjectCommittedHandler(const Endpoint::Ptr& sender, const RequestMessage& request); void RemoteObjectUpdateHandler(const Endpoint::Ptr& sender, const RequestMessage& request);
void RemoteObjectRemovedHandler(const RequestMessage& request); void RemoteObjectRemovedHandler(const RequestMessage& request);
static RequestMessage MakeObjectMessage(const DynamicObject::Ptr& object, static RequestMessage MakeObjectMessage(const DynamicObject::Ptr& object,
string method, bool includeProperties); const String& method, double sinceTx, bool includeProperties);
static bool ShouldReplicateObject(const DynamicObject::Ptr& object); static bool ShouldReplicateObject(const DynamicObject::Ptr& object);
}; };

View File

@ -86,7 +86,7 @@ void CompatComponent::DumpHostObject(ofstream& fp, const Host::Ptr& host)
<< "\t" << "active_checks_enabled" << "\t" << 1 << "\n" << "\t" << "active_checks_enabled" << "\t" << 1 << "\n"
<< "\t" << "passive_checks_enabled" << "\t" << 1 << "\n"; << "\t" << "passive_checks_enabled" << "\t" << 1 << "\n";
set<string> parents = host->GetParents(); set<String> parents = host->GetParents();
if (!parents.empty()) { if (!parents.empty()) {
fp << "\t" << "parents" << "\t"; fp << "\t" << "parents" << "\t";
@ -100,18 +100,19 @@ void CompatComponent::DumpHostObject(ofstream& fp, const Host::Ptr& host)
void CompatComponent::DumpServiceStatus(ofstream& fp, const Service::Ptr& service) void CompatComponent::DumpServiceStatus(ofstream& fp, const Service::Ptr& service)
{ {
string output; String output;
string perfdata; String perfdata;
double schedule_start = -1, schedule_end = -1; double schedule_start = -1, schedule_end = -1;
double execution_start = -1, execution_end = -1; double execution_start = -1, execution_end = -1;
if (service->HasLastCheckResult()) {
CheckResult cr = service->GetLastCheckResult(); Dictionary::Ptr cr = service->GetLastCheckResult();
output = cr.GetOutput(); if (cr) {
schedule_start = cr.GetScheduleStart(); output = cr->Get("output");
schedule_end = cr.GetScheduleEnd(); schedule_start = cr->Get("schedule_start");
execution_start = cr.GetExecutionStart(); schedule_end = cr->Get("schedule_end");
execution_end = cr.GetExecutionEnd(); execution_start = cr->Get("execution_start");
perfdata = cr.GetPerformanceDataRaw(); execution_end = cr->Get("execution_end");
perfdata = cr->Get("performance_data_raw");
} }
double execution_time = (execution_end - execution_start); double execution_time = (execution_end - execution_start);
@ -122,9 +123,9 @@ void CompatComponent::DumpServiceStatus(ofstream& fp, const Service::Ptr& servic
if (!service->IsReachable()) { if (!service->IsReachable()) {
state = StateCritical; state = StateCritical;
string text = "One or more parent services are unavailable."; String text = "One or more parent services are unavailable.";
if (output.empty()) if (output.IsEmpty())
output = text; output = text;
else else
output = text + " (" + output + ")"; output = text + " (" + output + ")";
@ -138,7 +139,7 @@ void CompatComponent::DumpServiceStatus(ofstream& fp, const Service::Ptr& servic
<< "\t" << "service_description=" << service->GetAlias() << "\n" << "\t" << "service_description=" << service->GetAlias() << "\n"
<< "\t" << "check_interval=" << service->GetCheckInterval() / 60.0 << "\n" << "\t" << "check_interval=" << service->GetCheckInterval() / 60.0 << "\n"
<< "\t" << "retry_interval=" << service->GetRetryInterval() / 60.0 << "\n" << "\t" << "retry_interval=" << service->GetRetryInterval() / 60.0 << "\n"
<< "\t" << "has_been_checked=" << (service->HasLastCheckResult() ? 1 : 0) << "\n" << "\t" << "has_been_checked=" << (service->GetLastCheckResult() ? 1 : 0) << "\n"
<< "\t" << "should_be_scheduled=1" << "\n" << "\t" << "should_be_scheduled=1" << "\n"
<< "\t" << "check_execution_time=" << execution_time << "\n" << "\t" << "check_execution_time=" << execution_time << "\n"
<< "\t" << "check_latency=" << latency << "\n" << "\t" << "check_latency=" << latency << "\n"
@ -220,7 +221,7 @@ void CompatComponent::StatusTimerHandler(void)
<< "# This file is auto-generated. Do not modify this file." << "\n" << "# This file is auto-generated. Do not modify this file." << "\n"
<< "\n"; << "\n";
map<string, vector<string> > hostgroups; map<String, vector<String> > hostgroups;
DynamicObject::Ptr object; DynamicObject::Ptr object;
BOOST_FOREACH(tie(tuples::ignore, object), DynamicObject::GetObjects("Host")) { BOOST_FOREACH(tie(tuples::ignore, object), DynamicObject::GetObjects("Host")) {
@ -230,7 +231,7 @@ void CompatComponent::StatusTimerHandler(void)
dict = host->GetGroups(); dict = host->GetGroups();
if (dict) { if (dict) {
Variant hostgroup; Value hostgroup;
BOOST_FOREACH(tie(tuples::ignore, hostgroup), dict) { BOOST_FOREACH(tie(tuples::ignore, hostgroup), dict) {
hostgroups[hostgroup].push_back(host->GetName()); hostgroups[hostgroup].push_back(host->GetName());
} }
@ -240,10 +241,10 @@ void CompatComponent::StatusTimerHandler(void)
DumpHostObject(objectfp, host); DumpHostObject(objectfp, host);
} }
pair<string, vector<string > > hgt; pair<String, vector<String > > hgt;
BOOST_FOREACH(hgt, hostgroups) { BOOST_FOREACH(hgt, hostgroups) {
const string& name = hgt.first; const String& name = hgt.first;
const vector<string>& hosts = hgt.second; const vector<String>& hosts = hgt.second;
objectfp << "define hostgroup {" << "\n" objectfp << "define hostgroup {" << "\n"
<< "\t" << "hostgroup_name" << "\t" << name << "\n"; << "\t" << "hostgroup_name" << "\t" << name << "\n";
@ -263,7 +264,7 @@ void CompatComponent::StatusTimerHandler(void)
<< "}" << "\n"; << "}" << "\n";
} }
map<string, vector<Service::Ptr> > servicegroups; map<String, vector<Service::Ptr> > servicegroups;
BOOST_FOREACH(tie(tuples::ignore, object), DynamicObject::GetObjects("Service")) { BOOST_FOREACH(tie(tuples::ignore, object), DynamicObject::GetObjects("Service")) {
Service::Ptr service = static_pointer_cast<Service>(object); Service::Ptr service = static_pointer_cast<Service>(object);
@ -273,7 +274,7 @@ void CompatComponent::StatusTimerHandler(void)
dict = service->GetGroups(); dict = service->GetGroups();
if (dict) { if (dict) {
Variant servicegroup; Value servicegroup;
BOOST_FOREACH(tie(tuples::ignore, servicegroup), dict) { BOOST_FOREACH(tie(tuples::ignore, servicegroup), dict) {
servicegroups[servicegroup].push_back(service); servicegroups[servicegroup].push_back(service);
} }
@ -283,9 +284,9 @@ void CompatComponent::StatusTimerHandler(void)
DumpServiceObject(objectfp, service); DumpServiceObject(objectfp, service);
} }
pair<string, vector<Service::Ptr> > sgt; pair<String, vector<Service::Ptr> > sgt;
BOOST_FOREACH(sgt, servicegroups) { BOOST_FOREACH(sgt, servicegroups) {
const string& name = sgt.first; const String& name = sgt.first;
const vector<Service::Ptr>& services = sgt.second; const vector<Service::Ptr>& services = sgt.second;
objectfp << "define servicegroup {" << "\n" objectfp << "define servicegroup {" << "\n"
@ -300,7 +301,7 @@ void CompatComponent::StatusTimerHandler(void)
objectfp << "\t" << "members" << "\t"; objectfp << "\t" << "members" << "\t";
vector<string> sglist; vector<String> sglist;
vector<Service::Ptr>::iterator vt; vector<Service::Ptr>::iterator vt;
BOOST_FOREACH(const Service::Ptr& service, services) { BOOST_FOREACH(const Service::Ptr& service, services) {

View File

@ -78,21 +78,21 @@ void ConvenienceComponent::HostCommittedHandler(const ConfigItem::Ptr& item)
return; return;
Dictionary::Ptr oldServices; Dictionary::Ptr oldServices;
host->GetTag("convenience-services", &oldServices); host->GetAttribute("convenience_services", &oldServices);
Dictionary::Ptr newServices; Dictionary::Ptr newServices;
newServices = boost::make_shared<Dictionary>(); newServices = boost::make_shared<Dictionary>();
Dictionary::Ptr serviceDescs; Dictionary::Ptr serviceDescs;
host->GetProperty("services", &serviceDescs); host->GetAttribute("services", &serviceDescs);
if (serviceDescs) { if (serviceDescs) {
string svcname; String svcname;
Variant svcdesc; Value svcdesc;
BOOST_FOREACH(tie(svcname, svcdesc), serviceDescs) { BOOST_FOREACH(tie(svcname, svcdesc), serviceDescs) {
stringstream namebuf; stringstream namebuf;
namebuf << item->GetName() << "-" << svcname; namebuf << item->GetName() << "-" << svcname;
string name = namebuf.str(); String name = namebuf.str();
ConfigItemBuilder::Ptr builder = boost::make_shared<ConfigItemBuilder>(item->GetDebugInfo()); ConfigItemBuilder::Ptr builder = boost::make_shared<ConfigItemBuilder>(item->GetDebugInfo());
builder->SetType("service"); builder->SetType("service");
@ -107,7 +107,7 @@ void ConvenienceComponent::HostCommittedHandler(const ConfigItem::Ptr& item)
} else if (svcdesc.IsObjectType<Dictionary>()) { } else if (svcdesc.IsObjectType<Dictionary>()) {
Dictionary::Ptr service = svcdesc; Dictionary::Ptr service = svcdesc;
string parent; String parent;
if (!service->Get("service", &parent)) if (!service->Get("service", &parent))
parent = svcname; parent = svcname;
@ -136,7 +136,7 @@ void ConvenienceComponent::HostCommittedHandler(const ConfigItem::Ptr& item)
} }
} }
host->SetTag("convenience-services", newServices); host->SetAttribute("convenience_services", newServices);
} }
void ConvenienceComponent::HostRemovedHandler(const ConfigItem::Ptr& item) void ConvenienceComponent::HostRemovedHandler(const ConfigItem::Ptr& item)
@ -150,7 +150,7 @@ void ConvenienceComponent::HostRemovedHandler(const ConfigItem::Ptr& item)
return; return;
Dictionary::Ptr services; Dictionary::Ptr services;
host->GetTag("convenience-services", &services); host->GetAttribute("convenience_services", &services);
if (!services) if (!services)
return; return;

View File

@ -24,8 +24,8 @@ using namespace icinga;
void DelegationComponent::Start(void) void DelegationComponent::Start(void)
{ {
DynamicObject::OnCommitted.connect(boost::bind(&DelegationComponent::ServiceCommittedHandler, this, _1)); DynamicObject::OnRegistered.connect(boost::bind(&DelegationComponent::ServiceCommittedHandler, this, _1));
DynamicObject::OnRemoved.connect(boost::bind(&DelegationComponent::ServiceRemovedHandler, this, _1)); DynamicObject::OnUnregistered.connect(boost::bind(&DelegationComponent::ServiceRemovedHandler, this, _1));
m_DelegationTimer = boost::make_shared<Timer>(); m_DelegationTimer = boost::make_shared<Timer>();
m_DelegationTimer->SetInterval(30); m_DelegationTimer->SetInterval(30);
@ -57,9 +57,9 @@ void DelegationComponent::ServiceCommittedHandler(const DynamicObject::Ptr& obje
if (!service) if (!service)
return; return;
string checker = service->GetChecker(); String checker = service->GetChecker();
if (!checker.empty()) { if (!checker.IsEmpty()) {
/* object was updated, clear its checker to make sure it's re-delegated by the delegation timer */ /* object was updated, clear its checker to make sure it's re-delegated by the delegation timer */
service->SetChecker(""); service->SetChecker("");
@ -78,9 +78,9 @@ void DelegationComponent::ServiceRemovedHandler(const DynamicObject::Ptr& object
if (!service) if (!service)
return; return;
string checker = service->GetChecker(); String checker = service->GetChecker();
if (!checker.empty()) { if (!checker.IsEmpty()) {
/* TODO: figure out a better way to clear individual services */ /* TODO: figure out a better way to clear individual services */
Endpoint::Ptr endpoint = EndpointManager::GetInstance()->GetEndpointByIdentity(checker); Endpoint::Ptr endpoint = EndpointManager::GetInstance()->GetEndpointByIdentity(checker);
@ -195,8 +195,8 @@ void DelegationComponent::DelegationTimerHandler(void)
services.push_back(service); services.push_back(service);
string checker = service->GetChecker(); String checker = service->GetChecker();
if (checker.empty()) if (checker.IsEmpty())
continue; continue;
Endpoint::Ptr endpoint = EndpointManager::GetInstance()->GetEndpointByIdentity(checker); Endpoint::Ptr endpoint = EndpointManager::GetInstance()->GetEndpointByIdentity(checker);
@ -213,10 +213,10 @@ void DelegationComponent::DelegationTimerHandler(void)
/* re-assign services */ /* re-assign services */
BOOST_FOREACH(const Service::Ptr& service, services) { BOOST_FOREACH(const Service::Ptr& service, services) {
string checker = service->GetChecker(); String checker = service->GetChecker();
Endpoint::Ptr oldEndpoint; Endpoint::Ptr oldEndpoint;
if (!checker.empty()) if (!checker.IsEmpty())
oldEndpoint = EndpointManager::GetInstance()->GetEndpointByIdentity(checker); oldEndpoint = EndpointManager::GetInstance()->GetEndpointByIdentity(checker);
vector<Endpoint::Ptr> candidates = GetCheckerCandidates(service); vector<Endpoint::Ptr> candidates = GetCheckerCandidates(service);
@ -247,7 +247,7 @@ void DelegationComponent::DelegationTimerHandler(void)
continue; continue;
/* clear the service's current checker */ /* clear the service's current checker */
if (!checker.empty()) { if (!checker.IsEmpty()) {
need_clear = true; need_clear = true;
service->SetChecker(""); service->SetChecker("");
@ -269,7 +269,7 @@ void DelegationComponent::DelegationTimerHandler(void)
break; break;
} }
assert(candidates.size() == 0 || !service->GetChecker().empty()); assert(candidates.size() == 0 || !service->GetChecker().IsEmpty());
} }
Endpoint::Ptr endpoint; Endpoint::Ptr endpoint;
@ -289,7 +289,7 @@ void DelegationComponent::DelegationTimerHandler(void)
} }
BOOST_FOREACH(const Service::Ptr& service, services) { BOOST_FOREACH(const Service::Ptr& service, services) {
string checker = service->GetChecker(); String checker = service->GetChecker();
Endpoint::Ptr endpoint = EndpointManager::GetInstance()->GetEndpointByIdentity(checker); Endpoint::Ptr endpoint = EndpointManager::GetInstance()->GetEndpointByIdentity(checker);
if (!endpoint) if (!endpoint)

View File

@ -21,16 +21,6 @@
using namespace icinga; using namespace icinga;
/**
* Returns the name of the component.
*
* @returns The name.
*/
string DemoComponent::GetName(void) const
{
return "demo";
}
/** /**
* Starts the component. * Starts the component.
*/ */

View File

@ -29,7 +29,6 @@ namespace icinga
class DemoComponent : public IComponent class DemoComponent : public IComponent
{ {
public: public:
virtual string GetName(void) const;
virtual void Start(void); virtual void Start(void);
virtual void Stop(void); virtual void Stop(void);

View File

@ -107,7 +107,7 @@ void DiscoveryComponent::NewEndpointHandler(const Endpoint::Ptr& endpoint)
/* accept discovery::Welcome messages from any endpoint */ /* accept discovery::Welcome messages from any endpoint */
endpoint->RegisterPublication("discovery::Welcome"); endpoint->RegisterPublication("discovery::Welcome");
string identity = endpoint->GetIdentity(); String identity = endpoint->GetIdentity();
if (identity == EndpointManager::GetInstance()->GetIdentity()) { if (identity == EndpointManager::GetInstance()->GetIdentity()) {
Logger::Write(LogWarning, "discovery", "Detected loop-back connection - Disconnecting endpoint."); Logger::Write(LogWarning, "discovery", "Detected loop-back connection - Disconnecting endpoint.");
@ -129,7 +129,7 @@ void DiscoveryComponent::NewEndpointHandler(const Endpoint::Ptr& endpoint)
// the broker knows about our message types // the broker knows about our message types
SendDiscoveryMessage("discovery::RegisterComponent", EndpointManager::GetInstance()->GetIdentity(), endpoint); SendDiscoveryMessage("discovery::RegisterComponent", EndpointManager::GetInstance()->GetIdentity(), endpoint);
map<string, ComponentDiscoveryInfo::Ptr>::iterator ic; map<String, ComponentDiscoveryInfo::Ptr>::iterator ic;
// we assume the other component _always_ wants // we assume the other component _always_ wants
// discovery::NewComponent messages from us // discovery::NewComponent messages from us
@ -156,11 +156,11 @@ void DiscoveryComponent::NewEndpointHandler(const Endpoint::Ptr& endpoint)
// register published/subscribed topics for this endpoint // register published/subscribed topics for this endpoint
ComponentDiscoveryInfo::Ptr info = ic->second; ComponentDiscoveryInfo::Ptr info = ic->second;
BOOST_FOREACH(string publication, info->Publications) { BOOST_FOREACH(String publication, info->Publications) {
endpoint->RegisterPublication(publication); endpoint->RegisterPublication(publication);
} }
BOOST_FOREACH(string subscription, info->Subscriptions) { BOOST_FOREACH(String subscription, info->Subscriptions) {
endpoint->RegisterSubscription(subscription); endpoint->RegisterSubscription(subscription);
} }
@ -192,7 +192,7 @@ void DiscoveryComponent::DiscoveryEndpointHandler(const Endpoint::Ptr& endpoint,
* @param info Pointer to the information object. * @param info Pointer to the information object.
* @returns true if the info object was successfully retrieved, false otherwise. * @returns true if the info object was successfully retrieved, false otherwise.
*/ */
bool DiscoveryComponent::GetComponentDiscoveryInfo(string component, ComponentDiscoveryInfo::Ptr *info) const bool DiscoveryComponent::GetComponentDiscoveryInfo(String component, ComponentDiscoveryInfo::Ptr *info) const
{ {
if (component == EndpointManager::GetInstance()->GetIdentity()) { if (component == EndpointManager::GetInstance()->GetIdentity()) {
/* Build fake discovery info for ourselves */ /* Build fake discovery info for ourselves */
@ -206,7 +206,7 @@ bool DiscoveryComponent::GetComponentDiscoveryInfo(string component, ComponentDi
return true; return true;
} }
map<string, ComponentDiscoveryInfo::Ptr>::const_iterator i; map<String, ComponentDiscoveryInfo::Ptr>::const_iterator i;
i = m_Components.find(component); i = m_Components.find(component);
@ -267,7 +267,7 @@ void DiscoveryComponent::FinishDiscoverySetup(const Endpoint::Ptr& endpoint)
* @param identity The identity of the component for which a message should be sent. * @param identity The identity of the component for which a message should be sent.
* @param recipient The recipient of the message. A multicast message is sent if this parameter is empty. * @param recipient The recipient of the message. A multicast message is sent if this parameter is empty.
*/ */
void DiscoveryComponent::SendDiscoveryMessage(const string& method, const string& identity, const Endpoint::Ptr& recipient) void DiscoveryComponent::SendDiscoveryMessage(const String& method, const String& identity, const Endpoint::Ptr& recipient)
{ {
RequestMessage request; RequestMessage request;
request.SetMethod(method); request.SetMethod(method);
@ -282,21 +282,21 @@ void DiscoveryComponent::SendDiscoveryMessage(const string& method, const string
if (!GetComponentDiscoveryInfo(identity, &info)) if (!GetComponentDiscoveryInfo(identity, &info))
return; return;
if (!info->Node.empty() && !info->Service.empty()) { if (!info->Node.IsEmpty() && !info->Service.IsEmpty()) {
params.SetNode(info->Node); params.SetNode(info->Node);
params.SetService(info->Service); params.SetService(info->Service);
} }
set<string>::iterator i; set<String>::iterator i;
Dictionary::Ptr subscriptions = boost::make_shared<Dictionary>(); Dictionary::Ptr subscriptions = boost::make_shared<Dictionary>();
BOOST_FOREACH(string subscription, info->Subscriptions) { BOOST_FOREACH(String subscription, info->Subscriptions) {
subscriptions->Add(subscription); subscriptions->Add(subscription);
} }
params.SetSubscriptions(subscriptions); params.SetSubscriptions(subscriptions);
Dictionary::Ptr publications = boost::make_shared<Dictionary>(); Dictionary::Ptr publications = boost::make_shared<Dictionary>();
BOOST_FOREACH(string publication, info->Publications) { BOOST_FOREACH(String publication, info->Publications) {
publications->Add(publication); publications->Add(publication);
} }
@ -308,18 +308,19 @@ void DiscoveryComponent::SendDiscoveryMessage(const string& method, const string
EndpointManager::GetInstance()->SendMulticastMessage(m_Endpoint, request); EndpointManager::GetInstance()->SendMulticastMessage(m_Endpoint, request);
} }
bool DiscoveryComponent::HasMessagePermission(const Dictionary::Ptr& roles, const string& messageType, const string& message) bool DiscoveryComponent::HasMessagePermission(const Dictionary::Ptr& roles, const String& messageType, const String& message)
{ {
if (!roles) if (!roles)
return false; return false;
DynamicObject::Ptr role; Value roleName;
BOOST_FOREACH(tie(tuples::ignore, role), DynamicObject::GetObjects("Role")) { BOOST_FOREACH(tie(tuples::ignore, roleName), roles) {
DynamicObject::Ptr role = DynamicObject::GetObject("Role", roleName);
Dictionary::Ptr permissions; Dictionary::Ptr permissions;
if (!role->GetProperty(messageType, &permissions)) if (!role->GetAttribute(messageType, &permissions))
continue; continue;
Variant permission; Value permission;
BOOST_FOREACH(tie(tuples::ignore, permission), permissions) { BOOST_FOREACH(tie(tuples::ignore, permission), permissions) {
if (Utility::Match(permission, message)) if (Utility::Match(permission, message))
return true; return true;
@ -337,7 +338,7 @@ bool DiscoveryComponent::HasMessagePermission(const Dictionary::Ptr& roles, cons
* @param message The discovery message. * @param message The discovery message.
* @param trusted Whether the message comes from a trusted source (i.e. a broker). * @param trusted Whether the message comes from a trusted source (i.e. a broker).
*/ */
void DiscoveryComponent::ProcessDiscoveryMessage(const string& identity, const DiscoveryMessage& message, bool trusted) void DiscoveryComponent::ProcessDiscoveryMessage(const String& identity, const DiscoveryMessage& message, bool trusted)
{ {
/* ignore discovery messages that are about ourselves */ /* ignore discovery messages that are about ourselves */
if (identity == EndpointManager::GetInstance()->GetIdentity()) if (identity == EndpointManager::GetInstance()->GetIdentity())
@ -347,24 +348,24 @@ void DiscoveryComponent::ProcessDiscoveryMessage(const string& identity, const D
info->LastSeen = Utility::GetTime(); info->LastSeen = Utility::GetTime();
string node; String node;
if (message.GetNode(&node) && !node.empty()) if (message.GetNode(&node) && !node.IsEmpty())
info->Node = node; info->Node = node;
string service; String service;
if (message.GetService(&service) && !service.empty()) if (message.GetService(&service) && !service.IsEmpty())
info->Service = service; info->Service = service;
DynamicObject::Ptr endpointConfig = DynamicObject::GetObject("endpoint", identity); DynamicObject::Ptr endpointConfig = DynamicObject::GetObject("endpoint", identity);
Dictionary::Ptr roles; Dictionary::Ptr roles;
if (endpointConfig) if (endpointConfig)
endpointConfig->GetProperty("roles", &roles); endpointConfig->GetAttribute("roles", &roles);
Endpoint::Ptr endpoint = EndpointManager::GetInstance()->GetEndpointByIdentity(identity); Endpoint::Ptr endpoint = EndpointManager::GetInstance()->GetEndpointByIdentity(identity);
Dictionary::Ptr publications; Dictionary::Ptr publications;
if (message.GetPublications(&publications)) { if (message.GetPublications(&publications)) {
Variant publication; Value publication;
BOOST_FOREACH(tie(tuples::ignore, publication), publications) { BOOST_FOREACH(tie(tuples::ignore, publication), publications) {
if (trusted || HasMessagePermission(roles, "publications", publication)) { if (trusted || HasMessagePermission(roles, "publications", publication)) {
info->Publications.insert(publication); info->Publications.insert(publication);
@ -376,7 +377,7 @@ void DiscoveryComponent::ProcessDiscoveryMessage(const string& identity, const D
Dictionary::Ptr subscriptions; Dictionary::Ptr subscriptions;
if (message.GetSubscriptions(&subscriptions)) { if (message.GetSubscriptions(&subscriptions)) {
Variant subscription; Value subscription;
BOOST_FOREACH(tie(tuples::ignore, subscription), subscriptions) { BOOST_FOREACH(tie(tuples::ignore, subscription), subscriptions) {
if (trusted || HasMessagePermission(roles, "subscriptions", subscription)) { if (trusted || HasMessagePermission(roles, "subscriptions", subscription)) {
info->Subscriptions.insert(subscription); info->Subscriptions.insert(subscription);
@ -386,7 +387,7 @@ void DiscoveryComponent::ProcessDiscoveryMessage(const string& identity, const D
} }
} }
map<string, ComponentDiscoveryInfo::Ptr>::iterator i; map<String, ComponentDiscoveryInfo::Ptr>::iterator i;
i = m_Components.find(identity); i = m_Components.find(identity);
@ -412,7 +413,7 @@ void DiscoveryComponent::NewComponentMessageHandler(const RequestMessage& reques
DiscoveryMessage message; DiscoveryMessage message;
request.GetParams(&message); request.GetParams(&message);
string identity; String identity;
if (!message.GetIdentity(&identity)) if (!message.GetIdentity(&identity))
return; return;
@ -448,16 +449,16 @@ void DiscoveryComponent::DiscoveryTimerHandler(void)
if (endpointManager->GetEndpointByIdentity(object->GetName())) if (endpointManager->GetEndpointByIdentity(object->GetName()))
continue; continue;
string node, service; String node, service;
if (object->GetProperty("node", &node) && object->GetProperty("service", &service)) { if (object->GetAttribute("node", &node) && object->GetAttribute("service", &service)) {
/* reconnect to this endpoint */ /* reconnect to this endpoint */
endpointManager->AddConnection(node, service); endpointManager->AddConnection(node, service);
} }
} }
map<string, ComponentDiscoveryInfo::Ptr>::iterator curr, i; map<String, ComponentDiscoveryInfo::Ptr>::iterator curr, i;
for (i = m_Components.begin(); i != m_Components.end(); ) { for (i = m_Components.begin(); i != m_Components.end(); ) {
const string& identity = i->first; const String& identity = i->first;
const ComponentDiscoveryInfo::Ptr& info = i->second; const ComponentDiscoveryInfo::Ptr& info = i->second;
curr = i; curr = i;
@ -491,7 +492,7 @@ void DiscoveryComponent::DiscoveryTimerHandler(void)
/* TODO: figure out whether we actually want to connect to this component */ /* TODO: figure out whether we actually want to connect to this component */
/* try and reconnect to this component */ /* try and reconnect to this component */
try { try {
if (!info->Node.empty() && !info->Service.empty()) if (!info->Node.IsEmpty() && !info->Service.IsEmpty())
endpointManager->AddConnection(info->Node, info->Service); endpointManager->AddConnection(info->Node, info->Service);
} catch (const exception& ex) { } catch (const exception& ex) {
stringstream msgbuf; stringstream msgbuf;

View File

@ -32,11 +32,11 @@ public:
typedef shared_ptr<ComponentDiscoveryInfo> Ptr; typedef shared_ptr<ComponentDiscoveryInfo> Ptr;
typedef weak_ptr<ComponentDiscoveryInfo> WeakPtr; typedef weak_ptr<ComponentDiscoveryInfo> WeakPtr;
string Node; String Node;
string Service; String Service;
set<string> Subscriptions; set<String> Subscriptions;
set<string> Publications; set<String> Publications;
double LastSeen; double LastSeen;
}; };
@ -52,7 +52,7 @@ public:
private: private:
VirtualEndpoint::Ptr m_Endpoint; VirtualEndpoint::Ptr m_Endpoint;
map<string, ComponentDiscoveryInfo::Ptr> m_Components; map<String, ComponentDiscoveryInfo::Ptr> m_Components;
Timer::Ptr m_DiscoveryTimer; Timer::Ptr m_DiscoveryTimer;
void NewEndpointHandler(const Endpoint::Ptr& endpoint); void NewEndpointHandler(const Endpoint::Ptr& endpoint);
@ -62,10 +62,10 @@ private:
void WelcomeMessageHandler(const Endpoint::Ptr& sender, const RequestMessage& request); void WelcomeMessageHandler(const Endpoint::Ptr& sender, const RequestMessage& request);
void SendDiscoveryMessage(const string& method, const string& identity, const Endpoint::Ptr& recipient); void SendDiscoveryMessage(const String& method, const String& identity, const Endpoint::Ptr& recipient);
void ProcessDiscoveryMessage(const string& identity, const DiscoveryMessage& message, bool trusted); void ProcessDiscoveryMessage(const String& identity, const DiscoveryMessage& message, bool trusted);
bool GetComponentDiscoveryInfo(string component, ComponentDiscoveryInfo::Ptr *info) const; bool GetComponentDiscoveryInfo(String component, ComponentDiscoveryInfo::Ptr *info) const;
void CheckExistingEndpoint(const Endpoint::Ptr& self, const Endpoint::Ptr& other); void CheckExistingEndpoint(const Endpoint::Ptr& self, const Endpoint::Ptr& other);
void DiscoveryEndpointHandler(const Endpoint::Ptr& endpoint, const ComponentDiscoveryInfo::Ptr& info) const; void DiscoveryEndpointHandler(const Endpoint::Ptr& endpoint, const ComponentDiscoveryInfo::Ptr& info) const;
@ -74,7 +74,7 @@ private:
void FinishDiscoverySetup(const Endpoint::Ptr& endpoint); void FinishDiscoverySetup(const Endpoint::Ptr& endpoint);
bool HasMessagePermission(const Dictionary::Ptr& roles, const string& messageType, const string& message); bool HasMessagePermission(const Dictionary::Ptr& roles, const String& messageType, const String& message);
static const int RegistrationTTL = 300; static const int RegistrationTTL = 300;
}; };

View File

@ -29,32 +29,32 @@ DiscoveryMessage::DiscoveryMessage(const MessagePart& message)
: MessagePart(message) : MessagePart(message)
{ } { }
bool DiscoveryMessage::GetIdentity(string *value) const bool DiscoveryMessage::GetIdentity(String *value) const
{ {
return Get("identity", value); return Get("identity", value);
} }
void DiscoveryMessage::SetIdentity(const string& value) void DiscoveryMessage::SetIdentity(const String& value)
{ {
Set("identity", value); Set("identity", value);
} }
bool DiscoveryMessage::GetNode(string *value) const bool DiscoveryMessage::GetNode(String *value) const
{ {
return Get("node", value); return Get("node", value);
} }
void DiscoveryMessage::SetNode(const string& value) void DiscoveryMessage::SetNode(const String& value)
{ {
Set("node", value); Set("node", value);
} }
bool DiscoveryMessage::GetService(string *value) const bool DiscoveryMessage::GetService(String *value) const
{ {
return Get("service", value); return Get("service", value);
} }
void DiscoveryMessage::SetService(const string& value) void DiscoveryMessage::SetService(const String& value)
{ {
Set("service", value); Set("service", value);
} }

View File

@ -32,14 +32,14 @@ public:
DiscoveryMessage(void); DiscoveryMessage(void);
DiscoveryMessage(const MessagePart& message); DiscoveryMessage(const MessagePart& message);
bool GetIdentity(string *value) const; bool GetIdentity(String *value) const;
void SetIdentity(const string& value); void SetIdentity(const String& value);
bool GetNode(string *value) const; bool GetNode(String *value) const;
void SetNode(const string& value); void SetNode(const String& value);
bool GetService(string *value) const; bool GetService(String *value) const;
void SetService(const string& value); void SetService(const String& value);
bool GetSubscriptions(Dictionary::Ptr *value) const; bool GetSubscriptions(Dictionary::Ptr *value) const;
void SetSubscriptions(const Dictionary::Ptr& value); void SetSubscriptions(const Dictionary::Ptr& value);

View File

@ -173,7 +173,7 @@ typedef union YYSTYPE
char *text; char *text;
double num; double num;
icinga::Variant *variant; icinga::Value *variant;
icinga::ExpressionOperator op; icinga::ExpressionOperator op;
@ -1636,7 +1636,7 @@ yyreduce:
/* Line 1806 of yacc.c */ /* Line 1806 of yacc.c */
#line 166 "config_parser.yy" #line 166 "config_parser.yy"
{ {
(yyval.variant) = new Variant(m_ExpressionLists.top()); (yyval.variant) = new Value(m_ExpressionLists.top());
m_ExpressionLists.pop(); m_ExpressionLists.pop();
} }
break; break;
@ -1699,7 +1699,7 @@ yyreduce:
/* Line 1806 of yacc.c */ /* Line 1806 of yacc.c */
#line 222 "config_parser.yy" #line 222 "config_parser.yy"
{ {
(yyval.variant) = new Variant((yyvsp[(1) - (1)].text)); (yyval.variant) = new Value((yyvsp[(1) - (1)].text));
free((yyvsp[(1) - (1)].text)); free((yyvsp[(1) - (1)].text));
} }
break; break;
@ -1709,7 +1709,7 @@ yyreduce:
/* Line 1806 of yacc.c */ /* Line 1806 of yacc.c */
#line 227 "config_parser.yy" #line 227 "config_parser.yy"
{ {
(yyval.variant) = new Variant((yyvsp[(1) - (1)].num)); (yyval.variant) = new Value((yyvsp[(1) - (1)].num));
} }
break; break;
@ -1718,7 +1718,7 @@ yyreduce:
/* Line 1806 of yacc.c */ /* Line 1806 of yacc.c */
#line 231 "config_parser.yy" #line 231 "config_parser.yy"
{ {
(yyval.variant) = new Variant(); (yyval.variant) = new Value();
} }
break; break;

View File

@ -116,7 +116,7 @@ typedef union YYSTYPE
char *text; char *text;
double num; double num;
icinga::Variant *variant; icinga::Value *variant;
icinga::ExpressionOperator op; icinga::ExpressionOperator op;

View File

@ -38,7 +38,7 @@ using namespace icinga;
%union { %union {
char *text; char *text;
double num; double num;
icinga::Variant *variant; icinga::Value *variant;
icinga::ExpressionOperator op; icinga::ExpressionOperator op;
} }
@ -164,7 +164,7 @@ expressionlist: '{'
expressions expressions
'}' '}'
{ {
$$ = new Variant(m_ExpressionLists.top()); $$ = new Value(m_ExpressionLists.top());
m_ExpressionLists.pop(); m_ExpressionLists.pop();
} }
; ;
@ -220,16 +220,16 @@ operator: T_EQUAL
simplevalue: T_STRING simplevalue: T_STRING
{ {
$$ = new Variant($1); $$ = new Value($1);
free($1); free($1);
} }
| T_NUMBER | T_NUMBER
{ {
$$ = new Variant($1); $$ = new Value($1);
} }
| T_NULL | T_NULL
{ {
$$ = new Variant(); $$ = new Value();
} }
; ;

View File

@ -23,7 +23,7 @@ using std::ifstream;
using namespace icinga; using namespace icinga;
ConfigCompiler::ConfigCompiler(const string& path, istream *input, HandleIncludeFunc includeHandler) ConfigCompiler::ConfigCompiler(const String& path, istream *input, HandleIncludeFunc includeHandler)
: m_Path(path), m_Input(input), m_HandleInclude(includeHandler) : m_Path(path), m_Input(input), m_HandleInclude(includeHandler)
{ {
InitializeScanner(); InitializeScanner();
@ -50,29 +50,29 @@ vector<ConfigItem::Ptr> ConfigCompiler::GetResult(void) const
return m_Result; return m_Result;
} }
string ConfigCompiler::GetPath(void) const String ConfigCompiler::GetPath(void) const
{ {
return m_Path; return m_Path;
} }
void ConfigCompiler::HandleInclude(const string& include) void ConfigCompiler::HandleInclude(const String& include)
{ {
string path = Utility::DirName(GetPath()) + "/" + include; String path = Utility::DirName(GetPath()) + "/" + include;
vector<ConfigItem::Ptr> items = m_HandleInclude(path); vector<ConfigItem::Ptr> items = m_HandleInclude(path);
std::copy(items.begin(), items.end(), back_inserter(m_Result)); std::copy(items.begin(), items.end(), back_inserter(m_Result));
} }
vector<ConfigItem::Ptr> ConfigCompiler::CompileStream(const string& path, istream *stream) vector<ConfigItem::Ptr> ConfigCompiler::CompileStream(const String& path, istream *stream)
{ {
ConfigCompiler ctx(path, stream); ConfigCompiler ctx(path, stream);
ctx.Compile(); ctx.Compile();
return ctx.GetResult(); return ctx.GetResult();
} }
vector<ConfigItem::Ptr> ConfigCompiler::CompileFile(const string& path) vector<ConfigItem::Ptr> ConfigCompiler::CompileFile(const String& path)
{ {
ifstream stream; ifstream stream;
stream.open(path.c_str(), ifstream::in); stream.open(path.CStr(), ifstream::in);
if (!stream) if (!stream)
throw_exception(invalid_argument("Could not open config file: " + path)); throw_exception(invalid_argument("Could not open config file: " + path));
@ -82,13 +82,13 @@ vector<ConfigItem::Ptr> ConfigCompiler::CompileFile(const string& path)
return CompileStream(path, &stream); return CompileStream(path, &stream);
} }
vector<ConfigItem::Ptr> ConfigCompiler::CompileText(const string& path, const string& text) vector<ConfigItem::Ptr> ConfigCompiler::CompileText(const String& path, const String& text)
{ {
stringstream stream(text); stringstream stream(text);
return CompileStream(path, &stream); return CompileStream(path, &stream);
} }
vector<ConfigItem::Ptr> ConfigCompiler::HandleFileInclude(const string& include) vector<ConfigItem::Ptr> ConfigCompiler::HandleFileInclude(const String& include)
{ {
/* TODO: implement wildcard includes */ /* TODO: implement wildcard includes */
return CompileFile(include); return CompileFile(include);

View File

@ -26,32 +26,32 @@ namespace icinga
class I2_DYN_API ConfigCompiler class I2_DYN_API ConfigCompiler
{ {
public: public:
typedef function<vector<ConfigItem::Ptr> (const string& include)> HandleIncludeFunc; typedef function<vector<ConfigItem::Ptr> (const String& include)> HandleIncludeFunc;
ConfigCompiler(const string& path, istream *input = &cin, ConfigCompiler(const String& path, istream *input = &cin,
HandleIncludeFunc includeHandler = &ConfigCompiler::HandleFileInclude); HandleIncludeFunc includeHandler = &ConfigCompiler::HandleFileInclude);
virtual ~ConfigCompiler(void); virtual ~ConfigCompiler(void);
void Compile(void); void Compile(void);
static vector<ConfigItem::Ptr> CompileStream(const string& path, istream *stream); static vector<ConfigItem::Ptr> CompileStream(const String& path, istream *stream);
static vector<ConfigItem::Ptr> CompileFile(const string& path); static vector<ConfigItem::Ptr> CompileFile(const String& path);
static vector<ConfigItem::Ptr> CompileText(const string& path, const string& text); static vector<ConfigItem::Ptr> CompileText(const String& path, const String& text);
static vector<ConfigItem::Ptr> HandleFileInclude(const string& include); static vector<ConfigItem::Ptr> HandleFileInclude(const String& include);
vector<ConfigItem::Ptr> GetResult(void) const; vector<ConfigItem::Ptr> GetResult(void) const;
string GetPath(void) const; String GetPath(void) const;
/* internally used methods */ /* internally used methods */
void HandleInclude(const string& include); void HandleInclude(const String& include);
void AddObject(const ConfigItem::Ptr& object); void AddObject(const ConfigItem::Ptr& object);
size_t ReadInput(char *buffer, size_t max_bytes); size_t ReadInput(char *buffer, size_t max_bytes);
void *GetScanner(void) const; void *GetScanner(void) const;
private: private:
string m_Path; String m_Path;
istream *m_Input; istream *m_Input;
HandleIncludeFunc m_HandleInclude; HandleIncludeFunc m_HandleInclude;

View File

@ -25,20 +25,20 @@ ConfigItem::ItemMap ConfigItem::m_Items;
boost::signal<void (const ConfigItem::Ptr&)> ConfigItem::OnCommitted; boost::signal<void (const ConfigItem::Ptr&)> ConfigItem::OnCommitted;
boost::signal<void (const ConfigItem::Ptr&)> ConfigItem::OnRemoved; boost::signal<void (const ConfigItem::Ptr&)> ConfigItem::OnRemoved;
ConfigItem::ConfigItem(const string& type, const string& name, ConfigItem::ConfigItem(const String& type, const String& name,
const ExpressionList::Ptr& exprl, const vector<string>& parents, const ExpressionList::Ptr& exprl, const vector<String>& parents,
const DebugInfo& debuginfo) const DebugInfo& debuginfo)
: m_Type(type), m_Name(name), m_ExpressionList(exprl), : m_Type(type), m_Name(name), m_ExpressionList(exprl),
m_Parents(parents), m_DebugInfo(debuginfo) m_Parents(parents), m_DebugInfo(debuginfo)
{ {
} }
string ConfigItem::GetType(void) const String ConfigItem::GetType(void) const
{ {
return m_Type; return m_Type;
} }
string ConfigItem::GetName(void) const String ConfigItem::GetName(void) const
{ {
return m_Name; return m_Name;
} }
@ -53,14 +53,14 @@ ExpressionList::Ptr ConfigItem::GetExpressionList(void) const
return m_ExpressionList; return m_ExpressionList;
} }
vector<string> ConfigItem::GetParents(void) const vector<String> ConfigItem::GetParents(void) const
{ {
return m_Parents; return m_Parents;
} }
void ConfigItem::CalculateProperties(Dictionary::Ptr dictionary) const void ConfigItem::CalculateProperties(const Dictionary::Ptr& dictionary) const
{ {
BOOST_FOREACH(const string& name, m_Parents) { BOOST_FOREACH(const String& name, m_Parents) {
ConfigItem::Ptr parent = ConfigItem::GetObject(GetType(), name); ConfigItem::Ptr parent = ConfigItem::GetObject(GetType(), name);
if (!parent) { if (!parent) {
@ -82,20 +82,38 @@ DynamicObject::Ptr ConfigItem::Commit(void)
Dictionary::Ptr properties = boost::make_shared<Dictionary>(); Dictionary::Ptr properties = boost::make_shared<Dictionary>();
CalculateProperties(properties); CalculateProperties(properties);
/* Create a fake update in the format that
* DynamicObject::ApplyUpdate expects. */
Dictionary::Ptr attrs = boost::make_shared<Dictionary>();
String key;
Value data;
BOOST_FOREACH(tie(key, data), properties) {
Dictionary::Ptr attr = boost::make_shared<Dictionary>();
attr->Set("data", data);
attr->Set("type", Attribute_Config);
attr->Set("tx", DynamicObject::GetCurrentTx());
attrs->Set(key, attr);
}
Dictionary::Ptr update = boost::make_shared<Dictionary>();
update->Set("attrs", attrs);
update->Set("configTx", DynamicObject::GetCurrentTx());
if (!dobj) if (!dobj)
dobj = DynamicObject::GetObject(GetType(), GetName()); dobj = DynamicObject::GetObject(GetType(), GetName());
if (!dobj) if (!dobj)
dobj = DynamicObject::Create(GetType(), properties); dobj = DynamicObject::Create(GetType(), update);
else else
dobj->SetProperties(properties); dobj->ApplyUpdate(update);
m_DynamicObject = dobj; m_DynamicObject = dobj;
if (dobj->IsAbstract()) if (dobj->IsAbstract())
dobj->Unregister(); dobj->Unregister();
else else
dobj->Commit(); dobj->Register();
/* TODO: Figure out whether there are any child objects which inherit /* TODO: Figure out whether there are any child objects which inherit
* from this config item and Commit() them as well */ * from this config item and Commit() them as well */
@ -128,7 +146,7 @@ DynamicObject::Ptr ConfigItem::GetDynamicObject(void) const
return m_DynamicObject.lock(); return m_DynamicObject.lock();
} }
ConfigItem::Ptr ConfigItem::GetObject(const string& type, const string& name) ConfigItem::Ptr ConfigItem::GetObject(const String& type, const String& name)
{ {
ConfigItem::ItemMap::iterator it; ConfigItem::ItemMap::iterator it;
it = m_Items.find(make_pair(type, name)); it = m_Items.find(make_pair(type, name));

View File

@ -28,19 +28,17 @@ public:
typedef shared_ptr<ConfigItem> Ptr; typedef shared_ptr<ConfigItem> Ptr;
typedef weak_ptr<ConfigItem> WeakPtr; typedef weak_ptr<ConfigItem> WeakPtr;
ConfigItem(const string& type, const string& name, ConfigItem(const String& type, const String& name,
const ExpressionList::Ptr& exprl, const vector<string>& parents, const ExpressionList::Ptr& exprl, const vector<String>& parents,
const DebugInfo& debuginfo); const DebugInfo& debuginfo);
string GetType(void) const; String GetType(void) const;
string GetName(void) const; String GetName(void) const;
vector<string> GetParents(void) const; vector<String> GetParents(void) const;
ExpressionList::Ptr GetExpressionList(void) const; ExpressionList::Ptr GetExpressionList(void) const;
void CalculateProperties(Dictionary::Ptr dictionary) const;
DynamicObject::Ptr Commit(void); DynamicObject::Ptr Commit(void);
void Unregister(void); void Unregister(void);
@ -48,22 +46,24 @@ public:
DebugInfo GetDebugInfo(void) const; DebugInfo GetDebugInfo(void) const;
static ConfigItem::Ptr GetObject(const string& type, const string& name); static ConfigItem::Ptr GetObject(const String& type, const String& name);
static boost::signal<void (const ConfigItem::Ptr&)> OnCommitted; static boost::signal<void (const ConfigItem::Ptr&)> OnCommitted;
static boost::signal<void (const ConfigItem::Ptr&)> OnRemoved; static boost::signal<void (const ConfigItem::Ptr&)> OnRemoved;
private: private:
string m_Type; void CalculateProperties(const Dictionary::Ptr& dictionary) const;
string m_Name;
String m_Type;
String m_Name;
ExpressionList::Ptr m_ExpressionList; ExpressionList::Ptr m_ExpressionList;
vector<string> m_Parents; vector<String> m_Parents;
DebugInfo m_DebugInfo; DebugInfo m_DebugInfo;
DynamicObject::WeakPtr m_DynamicObject; DynamicObject::WeakPtr m_DynamicObject;
typedef map<pair<string, string>, ConfigItem::Ptr> ItemMap; typedef map<pair<String, String>, ConfigItem::Ptr> ItemMap;
static ItemMap m_Items; static ItemMap m_Items;
}; };

View File

@ -38,12 +38,12 @@ ConfigItemBuilder::ConfigItemBuilder(const DebugInfo& debugInfo)
m_DebugInfo = debugInfo; m_DebugInfo = debugInfo;
} }
void ConfigItemBuilder::SetType(const string& type) void ConfigItemBuilder::SetType(const String& type)
{ {
m_Type = type; m_Type = type;
} }
void ConfigItemBuilder::SetName(const string& name) void ConfigItemBuilder::SetName(const String& name)
{ {
m_Name = name; m_Name = name;
} }
@ -58,7 +58,7 @@ void ConfigItemBuilder::SetAbstract(bool abstract)
m_Abstract = abstract; m_Abstract = abstract;
} }
void ConfigItemBuilder::AddParent(const string& parent) void ConfigItemBuilder::AddParent(const String& parent)
{ {
m_Parents.push_back(parent); m_Parents.push_back(parent);
} }
@ -68,7 +68,7 @@ void ConfigItemBuilder::AddExpression(const Expression& expr)
m_ExpressionList->AddExpression(expr); m_ExpressionList->AddExpression(expr);
} }
void ConfigItemBuilder::AddExpression(const string& key, ExpressionOperator op, const Variant& value) void ConfigItemBuilder::AddExpression(const String& key, ExpressionOperator op, const Value& value)
{ {
Expression expr(key, op, value, m_DebugInfo); Expression expr(key, op, value, m_DebugInfo);
AddExpression(expr); AddExpression(expr);
@ -81,8 +81,8 @@ void ConfigItemBuilder::AddExpressionList(const ExpressionList::Ptr& exprl)
ConfigItem::Ptr ConfigItemBuilder::Compile(void) ConfigItem::Ptr ConfigItemBuilder::Compile(void)
{ {
assert(!m_Type.empty()); assert(!m_Type.IsEmpty());
assert(!m_Name.empty()); assert(!m_Name.IsEmpty());
ExpressionList::Ptr exprl = boost::make_shared<ExpressionList>(); ExpressionList::Ptr exprl = boost::make_shared<ExpressionList>();

View File

@ -32,25 +32,25 @@ public:
ConfigItemBuilder(void); ConfigItemBuilder(void);
ConfigItemBuilder(const DebugInfo& debugInfo); ConfigItemBuilder(const DebugInfo& debugInfo);
void SetType(const string& type); void SetType(const String& type);
void SetName(const string& name); void SetName(const String& name);
void SetLocal(bool local); void SetLocal(bool local);
void SetAbstract(bool abstract); void SetAbstract(bool abstract);
void AddParent(const string& parent); void AddParent(const String& parent);
void AddExpression(const Expression& expr); void AddExpression(const Expression& expr);
void AddExpression(const string& key, ExpressionOperator op, const Variant& value); void AddExpression(const String& key, ExpressionOperator op, const Value& value);
void AddExpressionList(const ExpressionList::Ptr& exprl); void AddExpressionList(const ExpressionList::Ptr& exprl);
ConfigItem::Ptr Compile(void); ConfigItem::Ptr Compile(void);
private: private:
string m_Type; String m_Type;
string m_Name; String m_Name;
bool m_Local; bool m_Local;
bool m_Abstract; bool m_Abstract;
vector<string> m_Parents; vector<String> m_Parents;
ExpressionList::Ptr m_ExpressionList; ExpressionList::Ptr m_ExpressionList;
DebugInfo m_DebugInfo; DebugInfo m_DebugInfo;
}; };

View File

@ -25,7 +25,7 @@ namespace icinga
struct DebugInfo struct DebugInfo
{ {
string Path; String Path;
union union
{ {

View File

@ -21,14 +21,14 @@
using namespace icinga; using namespace icinga;
Expression::Expression(const string& key, ExpressionOperator op, const Variant& value, const DebugInfo& debuginfo) Expression::Expression(const String& key, ExpressionOperator op, const Value& value, const DebugInfo& debuginfo)
: m_Key(key), m_Operator(op), m_Value(value), m_DebugInfo(debuginfo) : m_Key(key), m_Operator(op), m_Value(value), m_DebugInfo(debuginfo)
{ {
} }
void Expression::Execute(const Dictionary::Ptr& dictionary) const void Expression::Execute(const Dictionary::Ptr& dictionary) const
{ {
Variant oldValue, newValue; Value oldValue, newValue;
ExpressionList::Ptr valueExprl; ExpressionList::Ptr valueExprl;
Dictionary::Ptr valueDict; Dictionary::Ptr valueDict;
@ -61,7 +61,7 @@ void Expression::Execute(const Dictionary::Ptr& dictionary) const
break; break;
case OperatorPlus: case OperatorPlus:
dictionary->Get(m_Key, &oldValue); oldValue = dictionary->Get(m_Key);
if (oldValue.IsObjectType<Dictionary>()) if (oldValue.IsObjectType<Dictionary>())
dict = oldValue; dict = oldValue;
@ -81,8 +81,8 @@ void Expression::Execute(const Dictionary::Ptr& dictionary) const
if (valueExprl) { if (valueExprl) {
valueExprl->Execute(dict); valueExprl->Execute(dict);
} else if (valueDict) { } else if (valueDict) {
string key; String key;
Variant value; Value value;
BOOST_FOREACH(tie(key, value), valueDict) { BOOST_FOREACH(tie(key, value), valueDict) {
dict->Set(key, value); dict->Set(key, value);
} }

View File

@ -36,14 +36,14 @@ enum ExpressionOperator
struct I2_DYN_API Expression struct I2_DYN_API Expression
{ {
public: public:
Expression(const string& key, ExpressionOperator op, const Variant& value, const DebugInfo& debuginfo); Expression(const String& key, ExpressionOperator op, const Value& value, const DebugInfo& debuginfo);
void Execute(const Dictionary::Ptr& dictionary) const; void Execute(const Dictionary::Ptr& dictionary) const;
private: private:
string m_Key; String m_Key;
ExpressionOperator m_Operator; ExpressionOperator m_Operator;
Variant m_Value; Value m_Value;
DebugInfo m_DebugInfo; DebugInfo m_DebugInfo;
}; };

View File

@ -1,14 +1,14 @@
local object Application "icinga" { local object Application "icinga" {
/* cert = "icinga-c1.pem", cert = "icinga-c1.pem",
ca = "ca.crt", ca = "ca.crt",
node = "192.168.2.235", node = "192.168.2.235",
service = 7777*/ service = 7777
} }
/*local object Component "discovery" { local object Component "discovery" {
}*/ }
local object Component "checker" { local object Component "checker" {
@ -18,7 +18,11 @@ local object Component "delegation" {
} }
/*local object Endpoint "icinga-c2" { local object Component "compat" {
}
local object Endpoint "icinga-c2" {
roles = { "all" } roles = { "all" }
} }
@ -33,7 +37,7 @@ local object Endpoint "icinga-c4" {
local object Role "all" { local object Role "all" {
publications = { "*" }, publications = { "*" },
subscriptions = { "*" } subscriptions = { "*" }
}*/ }
object Host "localhost" { object Host "localhost" {

View File

@ -21,9 +21,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "icinga", "icinga\icinga.vcx
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "icinga-app", "icinga-app\icinga-app.vcxproj", "{BE412865-FEBA-4259-AD41-58950D1F5432}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "icinga-app", "icinga-app\icinga-app.vcxproj", "{BE412865-FEBA-4259-AD41-58950D1F5432}"
ProjectSection(ProjectDependencies) = postProject ProjectSection(ProjectDependencies) = postProject
{2BD1C70C-43DB-4F44-B66B-67CF5C7044AA} = {2BD1C70C-43DB-4F44-B66B-67CF5C7044AA}
{EAD41628-BB96-4F99-9070-8A9676801295} = {EAD41628-BB96-4F99-9070-8A9676801295} {EAD41628-BB96-4F99-9070-8A9676801295} = {EAD41628-BB96-4F99-9070-8A9676801295}
{2E6C1133-730F-4875-A72C-B455B1DD4C5C} = {2E6C1133-730F-4875-A72C-B455B1DD4C5C} {2E6C1133-730F-4875-A72C-B455B1DD4C5C} = {2E6C1133-730F-4875-A72C-B455B1DD4C5C}
{17C93245-8C20-4316-9573-1AE41D918C10} = {17C93245-8C20-4316-9573-1AE41D918C10} {17C93245-8C20-4316-9573-1AE41D918C10} = {17C93245-8C20-4316-9573-1AE41D918C10}
{704DDD8E-9E6D-4C22-80BD-6DE10F3A5E1C} = {704DDD8E-9E6D-4C22-80BD-6DE10F3A5E1C}
{D02A349B-BAF7-41FB-86FF-B05BA05FE578} = {D02A349B-BAF7-41FB-86FF-B05BA05FE578}
{38CE81CC-2660-4EF0-A936-4A337591DA3E} = {38CE81CC-2660-4EF0-A936-4A337591DA3E} {38CE81CC-2660-4EF0-A936-4A337591DA3E} = {38CE81CC-2660-4EF0-A936-4A337591DA3E}
{C1FC77E1-04A4-481B-A78B-2F7AF489C2F8} = {C1FC77E1-04A4-481B-A78B-2F7AF489C2F8} {C1FC77E1-04A4-481B-A78B-2F7AF489C2F8} = {C1FC77E1-04A4-481B-A78B-2F7AF489C2F8}
EndProjectSection EndProjectSection
@ -158,12 +161,12 @@ Global
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(NestedProjects) = preSolution GlobalSection(NestedProjects) = preSolution
{2E6C1133-730F-4875-A72C-B455B1DD4C5C} = {4A1773FD-DDED-4952-8700-C898E890554A}
{EAD41628-BB96-4F99-9070-8A9676801295} = {4A1773FD-DDED-4952-8700-C898E890554A} {EAD41628-BB96-4F99-9070-8A9676801295} = {4A1773FD-DDED-4952-8700-C898E890554A}
{38CE81CC-2660-4EF0-A936-4A337591DA3E} = {4A1773FD-DDED-4952-8700-C898E890554A} {38CE81CC-2660-4EF0-A936-4A337591DA3E} = {4A1773FD-DDED-4952-8700-C898E890554A}
{17C93245-8C20-4316-9573-1AE41D918C10} = {4A1773FD-DDED-4952-8700-C898E890554A} {17C93245-8C20-4316-9573-1AE41D918C10} = {4A1773FD-DDED-4952-8700-C898E890554A}
{704DDD8E-9E6D-4C22-80BD-6DE10F3A5E1C} = {4A1773FD-DDED-4952-8700-C898E890554A} {704DDD8E-9E6D-4C22-80BD-6DE10F3A5E1C} = {4A1773FD-DDED-4952-8700-C898E890554A}
{2BD1C70C-43DB-4F44-B66B-67CF5C7044AA} = {4A1773FD-DDED-4952-8700-C898E890554A} {2BD1C70C-43DB-4F44-B66B-67CF5C7044AA} = {4A1773FD-DDED-4952-8700-C898E890554A}
{D02A349B-BAF7-41FB-86FF-B05BA05FE578} = {4A1773FD-DDED-4952-8700-C898E890554A} {D02A349B-BAF7-41FB-86FF-B05BA05FE578} = {4A1773FD-DDED-4952-8700-C898E890554A}
{2E6C1133-730F-4875-A72C-B455B1DD4C5C} = {4A1773FD-DDED-4952-8700-C898E890554A}
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal

View File

@ -46,7 +46,7 @@ void Endpoint::SetEndpointManager(EndpointManager::WeakPtr manager)
* *
* @param topic The name of the topic. * @param topic The name of the topic.
*/ */
void Endpoint::RegisterSubscription(string topic) void Endpoint::RegisterSubscription(String topic)
{ {
m_Subscriptions.insert(topic); m_Subscriptions.insert(topic);
} }
@ -56,7 +56,7 @@ void Endpoint::RegisterSubscription(string topic)
* *
* @param topic The name of the topic. * @param topic The name of the topic.
*/ */
void Endpoint::UnregisterSubscription(string topic) void Endpoint::UnregisterSubscription(String topic)
{ {
m_Subscriptions.erase(topic); m_Subscriptions.erase(topic);
} }
@ -67,7 +67,7 @@ void Endpoint::UnregisterSubscription(string topic)
* @param topic The name of the topic. * @param topic The name of the topic.
* @returns true if the endpoint is subscribed to the topic, false otherwise. * @returns true if the endpoint is subscribed to the topic, false otherwise.
*/ */
bool Endpoint::HasSubscription(string topic) const bool Endpoint::HasSubscription(String topic) const
{ {
return (m_Subscriptions.find(topic) != m_Subscriptions.end()); return (m_Subscriptions.find(topic) != m_Subscriptions.end());
} }
@ -77,7 +77,7 @@ bool Endpoint::HasSubscription(string topic) const
* *
* @param topic The name of the topic. * @param topic The name of the topic.
*/ */
void Endpoint::RegisterPublication(string topic) void Endpoint::RegisterPublication(String topic)
{ {
m_Publications.insert(topic); m_Publications.insert(topic);
} }
@ -87,7 +87,7 @@ void Endpoint::RegisterPublication(string topic)
* *
* @param topic The name of the topic. * @param topic The name of the topic.
*/ */
void Endpoint::UnregisterPublication(string topic) void Endpoint::UnregisterPublication(String topic)
{ {
m_Publications.erase(topic); m_Publications.erase(topic);
} }
@ -98,7 +98,7 @@ void Endpoint::UnregisterPublication(string topic)
* @param topic The name of the topic. * @param topic The name of the topic.
* @returns true if the endpoint is publishing this topic, false otherwise. * @returns true if the endpoint is publishing this topic, false otherwise.
*/ */
bool Endpoint::HasPublication(string topic) const bool Endpoint::HasPublication(String topic) const
{ {
return (m_Publications.find(topic) != m_Publications.end()); return (m_Publications.find(topic) != m_Publications.end());
} }

View File

@ -36,14 +36,14 @@ public:
typedef shared_ptr<Endpoint> Ptr; typedef shared_ptr<Endpoint> Ptr;
typedef weak_ptr<Endpoint> WeakPtr; typedef weak_ptr<Endpoint> WeakPtr;
typedef set<string>::const_iterator ConstTopicIterator; typedef set<String>::const_iterator ConstTopicIterator;
Endpoint(void) Endpoint(void)
: m_ReceivedWelcome(false), m_SentWelcome(false) : m_ReceivedWelcome(false), m_SentWelcome(false)
{ } { }
virtual string GetIdentity(void) const = 0; virtual String GetIdentity(void) const = 0;
virtual string GetAddress(void) const = 0; virtual String GetAddress(void) const = 0;
void SetReceivedWelcome(bool value); void SetReceivedWelcome(bool value);
bool HasReceivedWelcome(void) const; bool HasReceivedWelcome(void) const;
@ -54,13 +54,13 @@ public:
shared_ptr<EndpointManager> GetEndpointManager(void) const; shared_ptr<EndpointManager> GetEndpointManager(void) const;
void SetEndpointManager(weak_ptr<EndpointManager> manager); void SetEndpointManager(weak_ptr<EndpointManager> manager);
void RegisterSubscription(string topic); void RegisterSubscription(String topic);
void UnregisterSubscription(string topic); void UnregisterSubscription(String topic);
bool HasSubscription(string topic) const; bool HasSubscription(String topic) const;
void RegisterPublication(string topic); void RegisterPublication(String topic);
void UnregisterPublication(string topic); void UnregisterPublication(String topic);
bool HasPublication(string topic) const; bool HasPublication(String topic) const;
virtual bool IsLocal(void) const = 0; virtual bool IsLocal(void) const = 0;
virtual bool IsConnected(void) const = 0; virtual bool IsConnected(void) const = 0;
@ -82,9 +82,9 @@ public:
boost::signal<void (const Endpoint::Ptr&)> OnSessionEstablished; boost::signal<void (const Endpoint::Ptr&)> OnSessionEstablished;
private: private:
set<string> m_Subscriptions; /**< The topics this endpoint is set<String> m_Subscriptions; /**< The topics this endpoint is
subscribed to. */ subscribed to. */
set<string> m_Publications; /**< The topics this endpoint is set<String> m_Publications; /**< The topics this endpoint is
publishing. */ publishing. */
bool m_ReceivedWelcome; /**< Have we received a welcome message bool m_ReceivedWelcome; /**< Have we received a welcome message
from this endpoint? */ from this endpoint? */

View File

@ -39,7 +39,7 @@ EndpointManager::EndpointManager(void)
* *
* @param identity The new identity. * @param identity The new identity.
*/ */
void EndpointManager::SetIdentity(const string& identity) void EndpointManager::SetIdentity(const String& identity)
{ {
m_Identity = identity; m_Identity = identity;
} }
@ -49,7 +49,7 @@ void EndpointManager::SetIdentity(const string& identity)
* *
* @returns The identity. * @returns The identity.
*/ */
string EndpointManager::GetIdentity(void) const String EndpointManager::GetIdentity(void) const
{ {
return m_Identity; return m_Identity;
} }
@ -79,7 +79,7 @@ shared_ptr<SSL_CTX> EndpointManager::GetSSLContext(void) const
* *
* @param service The port to listen on. * @param service The port to listen on.
*/ */
void EndpointManager::AddListener(const string& service) void EndpointManager::AddListener(const String& service)
{ {
if (!GetSSLContext()) if (!GetSSLContext())
throw_exception(logic_error("SSL context is required for AddListener()")); throw_exception(logic_error("SSL context is required for AddListener()"));
@ -102,7 +102,7 @@ void EndpointManager::AddListener(const string& service)
* @param node The remote host. * @param node The remote host.
* @param service The remote port. * @param service The remote port.
*/ */
void EndpointManager::AddConnection(const string& node, const string& service) void EndpointManager::AddConnection(const String& node, const String& service)
{ {
stringstream s; stringstream s;
s << "Adding new endpoint: [" << node << "]:" << service; s << "Adding new endpoint: [" << node << "]:" << service;
@ -164,9 +164,9 @@ void EndpointManager::RegisterEndpoint(const Endpoint::Ptr& endpoint)
UnregisterEndpoint(endpoint); UnregisterEndpoint(endpoint);
string identity = endpoint->GetIdentity(); String identity = endpoint->GetIdentity();
if (!identity.empty()) { if (!identity.IsEmpty()) {
m_Endpoints[identity] = endpoint; m_Endpoints[identity] = endpoint;
OnNewEndpoint(GetSelf(), endpoint); OnNewEndpoint(GetSelf(), endpoint);
} else { } else {
@ -200,8 +200,8 @@ void EndpointManager::UnregisterEndpoint(const Endpoint::Ptr& endpoint)
remove(m_PendingEndpoints.begin(), m_PendingEndpoints.end(), endpoint), remove(m_PendingEndpoints.begin(), m_PendingEndpoints.end(), endpoint),
m_PendingEndpoints.end()); m_PendingEndpoints.end());
string identity = endpoint->GetIdentity(); String identity = endpoint->GetIdentity();
if (!identity.empty()) if (!identity.IsEmpty())
m_Endpoints.erase(identity); m_Endpoints.erase(identity);
} }
@ -235,7 +235,7 @@ void EndpointManager::SendUnicastMessage(const Endpoint::Ptr& sender,
void EndpointManager::SendAnycastMessage(const Endpoint::Ptr& sender, void EndpointManager::SendAnycastMessage(const Endpoint::Ptr& sender,
const RequestMessage& message) const RequestMessage& message)
{ {
string method; String method;
if (!message.GetMethod(&method)) if (!message.GetMethod(&method))
throw_exception(invalid_argument("Message is missing the 'method' property.")); throw_exception(invalid_argument("Message is missing the 'method' property."));
@ -267,11 +267,11 @@ void EndpointManager::SendAnycastMessage(const Endpoint::Ptr& sender,
void EndpointManager::SendMulticastMessage(const Endpoint::Ptr& sender, void EndpointManager::SendMulticastMessage(const Endpoint::Ptr& sender,
const RequestMessage& message) const RequestMessage& message)
{ {
string id; String id;
if (message.GetID(&id)) if (message.GetID(&id))
throw_exception(invalid_argument("Multicast requests must not have an ID.")); throw_exception(invalid_argument("Multicast requests must not have an ID."));
string method; String method;
if (!message.GetMethod(&method)) if (!message.GetMethod(&method))
throw_exception(invalid_argument("Message is missing the 'method' property.")); throw_exception(invalid_argument("Message is missing the 'method' property."));
@ -293,7 +293,7 @@ void EndpointManager::SendMulticastMessage(const Endpoint::Ptr& sender,
*/ */
void EndpointManager::ForEachEndpoint(function<void (const EndpointManager::Ptr&, const Endpoint::Ptr&)> callback) void EndpointManager::ForEachEndpoint(function<void (const EndpointManager::Ptr&, const Endpoint::Ptr&)> callback)
{ {
map<string, Endpoint::Ptr>::iterator prev, i; map<String, Endpoint::Ptr>::iterator prev, i;
for (i = m_Endpoints.begin(); i != m_Endpoints.end(); ) { for (i = m_Endpoints.begin(); i != m_Endpoints.end(); ) {
prev = i; prev = i;
i++; i++;
@ -307,9 +307,9 @@ void EndpointManager::ForEachEndpoint(function<void (const EndpointManager::Ptr&
* *
* @param identity The identity of the endpoint. * @param identity The identity of the endpoint.
*/ */
Endpoint::Ptr EndpointManager::GetEndpointByIdentity(const string& identity) const Endpoint::Ptr EndpointManager::GetEndpointByIdentity(const String& identity) const
{ {
map<string, Endpoint::Ptr>::const_iterator i; map<String, Endpoint::Ptr>::const_iterator i;
i = m_Endpoints.find(identity); i = m_Endpoints.find(identity);
if (i != m_Endpoints.end()) if (i != m_Endpoints.end())
return i->second; return i->second;
@ -326,7 +326,7 @@ void EndpointManager::SendAPIMessage(const Endpoint::Ptr& sender, const Endpoint
stringstream idstream; stringstream idstream;
idstream << m_NextMessageID; idstream << m_NextMessageID;
string id = idstream.str(); String id = idstream.str();
message.SetID(id); message.SetID(id);
PendingRequest pr; PendingRequest pr;
@ -342,15 +342,15 @@ void EndpointManager::SendAPIMessage(const Endpoint::Ptr& sender, const Endpoint
SendUnicastMessage(sender, recipient, message); SendUnicastMessage(sender, recipient, message);
} }
bool EndpointManager::RequestTimeoutLessComparer(const pair<string, PendingRequest>& a, bool EndpointManager::RequestTimeoutLessComparer(const pair<String, PendingRequest>& a,
const pair<string, PendingRequest>& b) const pair<String, PendingRequest>& b)
{ {
return a.second.Timeout < b.second.Timeout; return a.second.Timeout < b.second.Timeout;
} }
void EndpointManager::RequestTimerHandler(void) void EndpointManager::RequestTimerHandler(void)
{ {
map<string, PendingRequest>::iterator it; map<String, PendingRequest>::iterator it;
for (it = m_Requests.begin(); it != m_Requests.end(); it++) { for (it = m_Requests.begin(); it != m_Requests.end(); it++) {
if (it->second.HasTimedOut()) { if (it->second.HasTimedOut()) {
it->second.Callback(GetSelf(), Endpoint::Ptr(), it->second.Request, ResponseMessage(), true); it->second.Callback(GetSelf(), Endpoint::Ptr(), it->second.Request, ResponseMessage(), true);
@ -364,11 +364,11 @@ void EndpointManager::RequestTimerHandler(void)
void EndpointManager::ProcessResponseMessage(const Endpoint::Ptr& sender, const ResponseMessage& message) void EndpointManager::ProcessResponseMessage(const Endpoint::Ptr& sender, const ResponseMessage& message)
{ {
string id; String id;
if (!message.GetID(&id)) if (!message.GetID(&id))
throw_exception(invalid_argument("Response message must have a message ID.")); throw_exception(invalid_argument("Response message must have a message ID."));
map<string, PendingRequest>::iterator it; map<String, PendingRequest>::iterator it;
it = m_Requests.find(id); it = m_Requests.find(id);
if (it == m_Requests.end()) if (it == m_Requests.end())

View File

@ -34,20 +34,20 @@ public:
typedef shared_ptr<EndpointManager> Ptr; typedef shared_ptr<EndpointManager> Ptr;
typedef weak_ptr<EndpointManager> WeakPtr; typedef weak_ptr<EndpointManager> WeakPtr;
typedef map<string, Endpoint::Ptr>::iterator Iterator; typedef map<String, Endpoint::Ptr>::iterator Iterator;
EndpointManager(void); EndpointManager(void);
static EndpointManager::Ptr GetInstance(void); static EndpointManager::Ptr GetInstance(void);
void SetIdentity(const string& identity); void SetIdentity(const String& identity);
string GetIdentity(void) const; String GetIdentity(void) const;
void SetSSLContext(const shared_ptr<SSL_CTX>& sslContext); void SetSSLContext(const shared_ptr<SSL_CTX>& sslContext);
shared_ptr<SSL_CTX> GetSSLContext(void) const; shared_ptr<SSL_CTX> GetSSLContext(void) const;
void AddListener(const string& service); void AddListener(const String& service);
void AddConnection(const string& node, const string& service); void AddConnection(const String& node, const String& service);
void RegisterEndpoint(const Endpoint::Ptr& endpoint); void RegisterEndpoint(const Endpoint::Ptr& endpoint);
void UnregisterEndpoint(const Endpoint::Ptr& endpoint); void UnregisterEndpoint(const Endpoint::Ptr& endpoint);
@ -65,17 +65,17 @@ public:
Iterator Begin(void); Iterator Begin(void);
Iterator End(void); Iterator End(void);
Endpoint::Ptr GetEndpointByIdentity(const string& identity) const; Endpoint::Ptr GetEndpointByIdentity(const String& identity) const;
boost::signal<void (const EndpointManager::Ptr&, const Endpoint::Ptr&)> OnNewEndpoint; boost::signal<void (const EndpointManager::Ptr&, const Endpoint::Ptr&)> OnNewEndpoint;
private: private:
string m_Identity; String m_Identity;
shared_ptr<SSL_CTX> m_SSLContext; shared_ptr<SSL_CTX> m_SSLContext;
vector<JsonRpcServer::Ptr> m_Servers; vector<JsonRpcServer::Ptr> m_Servers;
vector<Endpoint::Ptr> m_PendingEndpoints; vector<Endpoint::Ptr> m_PendingEndpoints;
map<string, Endpoint::Ptr> m_Endpoints; map<String, Endpoint::Ptr> m_Endpoints;
/** /**
* Information about a pending API request. * Information about a pending API request.
@ -95,13 +95,13 @@ private:
}; };
long m_NextMessageID; long m_NextMessageID;
map<string, PendingRequest> m_Requests; map<String, PendingRequest> m_Requests;
Timer::Ptr m_RequestTimer; Timer::Ptr m_RequestTimer;
void RegisterServer(const JsonRpcServer::Ptr& server); void RegisterServer(const JsonRpcServer::Ptr& server);
void UnregisterServer(const JsonRpcServer::Ptr& server); void UnregisterServer(const JsonRpcServer::Ptr& server);
static bool RequestTimeoutLessComparer(const pair<string, PendingRequest>& a, const pair<string, PendingRequest>& b); static bool RequestTimeoutLessComparer(const pair<String, PendingRequest>& a, const pair<String, PendingRequest>& b);
void RequestTimerHandler(void); void RequestTimerHandler(void);
void NewClientHandler(const TcpClient::Ptr& client); void NewClientHandler(const TcpClient::Ptr& client);

View File

@ -28,7 +28,7 @@
using namespace icinga; using namespace icinga;
const string IcingaApplication::DefaultPidPath = "icinga.pid"; const String IcingaApplication::DefaultPidPath = "icinga.pid";
IcingaApplication::IcingaApplication(void) IcingaApplication::IcingaApplication(void)
: m_PidPath(DefaultPidPath) : m_PidPath(DefaultPidPath)
@ -40,7 +40,7 @@ IcingaApplication::IcingaApplication(void)
* @param args Command-line arguments. * @param args Command-line arguments.
* @returns An exit status. * @returns An exit status.
*/ */
int IcingaApplication::Main(const vector<string>& args) int IcingaApplication::Main(const vector<String>& args)
{ {
/* create console logger */ /* create console logger */
ConfigItemBuilder::Ptr consoleLogConfig = boost::make_shared<ConfigItemBuilder>(); ConfigItemBuilder::Ptr consoleLogConfig = boost::make_shared<ConfigItemBuilder>();
@ -55,7 +55,7 @@ int IcingaApplication::Main(const vector<string>& args)
/* periodically dump the program state */ /* periodically dump the program state */
m_RetentionTimer = boost::make_shared<Timer>(); m_RetentionTimer = boost::make_shared<Timer>();
m_RetentionTimer->SetInterval(60); m_RetentionTimer->SetInterval(10);
m_RetentionTimer->OnTimerExpired.connect(boost::bind(&IcingaApplication::DumpProgramState, this)); m_RetentionTimer->OnTimerExpired.connect(boost::bind(&IcingaApplication::DumpProgramState, this));
m_RetentionTimer->Start(); m_RetentionTimer->Start();
@ -76,15 +76,15 @@ int IcingaApplication::Main(const vector<string>& args)
bool daemonize = false; bool daemonize = false;
bool parseOpts = true; bool parseOpts = true;
string configFile; String configFile;
/* TODO: clean up this mess; for now it will just have to do */ /* TODO: clean up this mess; for now it will just have to do */
vector<string>::const_iterator it; vector<String>::const_iterator it;
for (it = args.begin() + 1 ; it != args.end(); it++) { for (it = args.begin() + 1 ; it != args.end(); it++) {
string arg = *it; String arg = *it;
/* ignore empty arguments */ /* ignore empty arguments */
if (arg.empty()) if (arg.IsEmpty())
continue; continue;
if (arg == "--") { if (arg == "--") {
@ -107,10 +107,10 @@ int IcingaApplication::Main(const vector<string>& args)
throw_exception(invalid_argument("Trailing command line arguments after config filename.")); throw_exception(invalid_argument("Trailing command line arguments after config filename."));
} }
if (configFile.empty()) if (configFile.IsEmpty())
throw_exception(invalid_argument("No config file was specified on the command line.")); throw_exception(invalid_argument("No config file was specified on the command line."));
string componentDirectory = Utility::DirName(GetExePath()) + "/../lib/icinga2"; String componentDirectory = Utility::DirName(GetExePath()) + "/../lib/icinga2";
Component::AddSearchDir(componentDirectory); Component::AddSearchDir(componentDirectory);
/* load cibsync config component */ /* load cibsync config component */
@ -125,7 +125,7 @@ int IcingaApplication::Main(const vector<string>& args)
convenienceComponentConfig->SetType("Component"); convenienceComponentConfig->SetType("Component");
convenienceComponentConfig->SetName("convenience"); convenienceComponentConfig->SetName("convenience");
convenienceComponentConfig->SetLocal(true); convenienceComponentConfig->SetLocal(true);
convenienceComponentConfig->Compile()->Commit(); //convenienceComponentConfig->Compile()->Commit();
/* load config file */ /* load config file */
vector<ConfigItem::Ptr> configItems = ConfigCompiler::CompileFile(configFile); vector<ConfigItem::Ptr> configItems = ConfigCompiler::CompileFile(configFile);
@ -144,15 +144,16 @@ int IcingaApplication::Main(const vector<string>& args)
if (!icingaConfig->IsLocal()) if (!icingaConfig->IsLocal())
throw_exception(runtime_error("'icinga' application object must be 'local'.")); throw_exception(runtime_error("'icinga' application object must be 'local'."));
icingaConfig->GetProperty("cert", &m_CertificateFile); icingaConfig->GetAttribute("cert", &m_CertificateFile);
icingaConfig->GetProperty("ca", &m_CAFile); icingaConfig->GetAttribute("ca", &m_CAFile);
icingaConfig->GetProperty("node", &m_Node); icingaConfig->GetAttribute("node", &m_Node);
icingaConfig->GetProperty("service", &m_Service); icingaConfig->GetAttribute("service", &m_Service);
icingaConfig->GetProperty("pidpath", &m_PidPath); icingaConfig->GetAttribute("pidpath", &m_PidPath);
icingaConfig->GetProperty("macros", &m_Macros); icingaConfig->GetAttribute("macros", &m_Macros);
string logpath; String logpath;
if (icingaConfig->GetProperty("logpath", &logpath)) { icingaConfig->GetAttribute("logpath", &logpath);
if (!logpath.IsEmpty()) {
ConfigItemBuilder::Ptr fileLogConfig = boost::make_shared<ConfigItemBuilder>(); ConfigItemBuilder::Ptr fileLogConfig = boost::make_shared<ConfigItemBuilder>();
fileLogConfig->SetType("Logger"); fileLogConfig->SetType("Logger");
fileLogConfig->SetName("main"); fileLogConfig->SetName("main");
@ -164,10 +165,10 @@ int IcingaApplication::Main(const vector<string>& args)
UpdatePidFile(GetPidPath()); UpdatePidFile(GetPidPath());
if (!GetCertificateFile().empty() && !GetCAFile().empty()) { if (!GetCertificateFile().IsEmpty() && !GetCAFile().IsEmpty()) {
/* set up SSL context */ /* set up SSL context */
shared_ptr<X509> cert = Utility::GetX509Certificate(GetCertificateFile()); shared_ptr<X509> cert = Utility::GetX509Certificate(GetCertificateFile());
string identity = Utility::GetCertificateCN(cert); String identity = Utility::GetCertificateCN(cert);
Logger::Write(LogInformation, "icinga", "My identity: " + identity); Logger::Write(LogInformation, "icinga", "My identity: " + identity);
EndpointManager::GetInstance()->SetIdentity(identity); EndpointManager::GetInstance()->SetIdentity(identity);
@ -176,8 +177,8 @@ int IcingaApplication::Main(const vector<string>& args)
} }
/* create the primary RPC listener */ /* create the primary RPC listener */
string service = GetService(); String service = GetService();
if (!service.empty()) if (!service.IsEmpty())
EndpointManager::GetInstance()->AddListener(service); EndpointManager::GetInstance()->AddListener(service);
if (daemonize) { if (daemonize) {
@ -206,27 +207,27 @@ IcingaApplication::Ptr IcingaApplication::GetInstance(void)
return static_pointer_cast<IcingaApplication>(Application::GetInstance()); return static_pointer_cast<IcingaApplication>(Application::GetInstance());
} }
string IcingaApplication::GetCertificateFile(void) const String IcingaApplication::GetCertificateFile(void) const
{ {
return m_CertificateFile; return m_CertificateFile;
} }
string IcingaApplication::GetCAFile(void) const String IcingaApplication::GetCAFile(void) const
{ {
return m_CAFile; return m_CAFile;
} }
string IcingaApplication::GetNode(void) const String IcingaApplication::GetNode(void) const
{ {
return m_Node; return m_Node;
} }
string IcingaApplication::GetService(void) const String IcingaApplication::GetService(void) const
{ {
return m_Service; return m_Service;
} }
string IcingaApplication::GetPidPath(void) const String IcingaApplication::GetPidPath(void) const
{ {
return m_PidPath; return m_PidPath;
} }

View File

@ -36,27 +36,27 @@ public:
IcingaApplication(void); IcingaApplication(void);
int Main(const vector<string>& args); int Main(const vector<String>& args);
static IcingaApplication::Ptr GetInstance(void); static IcingaApplication::Ptr GetInstance(void);
string GetCertificateFile(void) const; String GetCertificateFile(void) const;
string GetCAFile(void) const; String GetCAFile(void) const;
string GetNode(void) const; String GetNode(void) const;
string GetService(void) const; String GetService(void) const;
string GetPidPath(void) const; String GetPidPath(void) const;
Dictionary::Ptr GetMacros(void) const; Dictionary::Ptr GetMacros(void) const;
time_t GetStartTime(void) const; time_t GetStartTime(void) const;
static const string DefaultPidPath; static const String DefaultPidPath;
private: private:
string m_CertificateFile; String m_CertificateFile;
string m_CAFile; String m_CAFile;
string m_Node; String m_Node;
string m_Service; String m_Service;
string m_PidPath; String m_PidPath;
Dictionary::Ptr m_Macros; Dictionary::Ptr m_Macros;
time_t m_StartTime; time_t m_StartTime;

View File

@ -21,12 +21,12 @@
using namespace icinga; using namespace icinga;
string JsonRpcEndpoint::GetIdentity(void) const String JsonRpcEndpoint::GetIdentity(void) const
{ {
return m_Identity; return m_Identity;
} }
string JsonRpcEndpoint::GetAddress(void) const String JsonRpcEndpoint::GetAddress(void) const
{ {
if (!m_Client) if (!m_Client)
return "<disconnected endpoint>"; return "<disconnected endpoint>";
@ -39,7 +39,7 @@ JsonRpcClient::Ptr JsonRpcEndpoint::GetClient(void)
return m_Client; return m_Client;
} }
void JsonRpcEndpoint::Connect(string node, string service, shared_ptr<SSL_CTX> sslContext) void JsonRpcEndpoint::Connect(String node, String service, shared_ptr<SSL_CTX> sslContext)
{ {
JsonRpcClient::Ptr client = boost::make_shared<JsonRpcClient>(RoleOutbound, sslContext); JsonRpcClient::Ptr client = boost::make_shared<JsonRpcClient>(RoleOutbound, sslContext);
SetClient(client); SetClient(client);
@ -92,14 +92,14 @@ void JsonRpcEndpoint::NewMessageHandler(const MessagePart& message)
RequestMessage request = message; RequestMessage request = message;
string method; String method;
if (!request.GetMethod(&method)) if (!request.GetMethod(&method))
return; return;
if (!HasPublication(method)) if (!HasPublication(method))
return; return;
string id; String id;
if (request.GetID(&id)) if (request.GetID(&id))
GetEndpointManager()->SendAnycastMessage(sender, request); GetEndpointManager()->SendAnycastMessage(sender, request);
else else
@ -137,9 +137,9 @@ void JsonRpcEndpoint::ClientClosedHandler(void)
void JsonRpcEndpoint::ClientConnectedHandler(void) void JsonRpcEndpoint::ClientConnectedHandler(void)
{ {
string identity = Utility::GetCertificateCN(m_Client->GetPeerCertificate()); String identity = Utility::GetCertificateCN(m_Client->GetPeerCertificate());
if (GetIdentity().empty() && !identity.empty()) { if (GetIdentity().IsEmpty() && !identity.IsEmpty()) {
m_Identity = identity; m_Identity = identity;
GetEndpointManager()->RegisterEndpoint(GetSelf()); GetEndpointManager()->RegisterEndpoint(GetSelf());
} }

View File

@ -35,14 +35,14 @@ public:
typedef shared_ptr<JsonRpcEndpoint> Ptr; typedef shared_ptr<JsonRpcEndpoint> Ptr;
typedef weak_ptr<JsonRpcEndpoint> WeakPtr; typedef weak_ptr<JsonRpcEndpoint> WeakPtr;
void Connect(string node, string service, void Connect(String node, String service,
shared_ptr<SSL_CTX> sslContext); shared_ptr<SSL_CTX> sslContext);
JsonRpcClient::Ptr GetClient(void); JsonRpcClient::Ptr GetClient(void);
void SetClient(JsonRpcClient::Ptr client); void SetClient(JsonRpcClient::Ptr client);
virtual string GetIdentity(void) const; virtual String GetIdentity(void) const;
virtual string GetAddress(void) const; virtual String GetAddress(void) const;
virtual bool IsLocal(void) const; virtual bool IsLocal(void) const;
virtual bool IsConnected(void) const; virtual bool IsConnected(void) const;
@ -53,13 +53,13 @@ public:
virtual void Stop(void); virtual void Stop(void);
private: private:
string m_Identity; /**< The identity of this endpoint. */ String m_Identity; /**< The identity of this endpoint. */
shared_ptr<SSL_CTX> m_SSLContext; shared_ptr<SSL_CTX> m_SSLContext;
string m_Address; String m_Address;
JsonRpcClient::Ptr m_Client; JsonRpcClient::Ptr m_Client;
void SetAddress(string address); void SetAddress(String address);
void NewMessageHandler(const MessagePart& message); void NewMessageHandler(const MessagePart& message);
void ClientClosedHandler(void); void ClientClosedHandler(void);

View File

@ -21,12 +21,12 @@
using namespace icinga; using namespace icinga;
string VirtualEndpoint::GetIdentity(void) const String VirtualEndpoint::GetIdentity(void) const
{ {
return "__" + GetAddress(); return "__" + GetAddress();
} }
string VirtualEndpoint::GetAddress(void) const String VirtualEndpoint::GetAddress(void) const
{ {
char address[50]; char address[50];
sprintf(address, "virtual:%p", (void *)this); sprintf(address, "virtual:%p", (void *)this);
@ -43,9 +43,9 @@ bool VirtualEndpoint::IsConnected(void) const
return true; return true;
} }
void VirtualEndpoint::RegisterTopicHandler(string topic, function<void (const VirtualEndpoint::Ptr&, const Endpoint::Ptr, const RequestMessage&)> callback) void VirtualEndpoint::RegisterTopicHandler(String topic, function<void (const VirtualEndpoint::Ptr&, const Endpoint::Ptr, const RequestMessage&)> callback)
{ {
map<string, shared_ptr<boost::signal<void (const VirtualEndpoint::Ptr&, const Endpoint::Ptr, const RequestMessage&)> > >::iterator it; map<String, shared_ptr<boost::signal<void (const VirtualEndpoint::Ptr&, const Endpoint::Ptr, const RequestMessage&)> > >::iterator it;
it = m_TopicHandlers.find(topic); it = m_TopicHandlers.find(topic);
shared_ptr<boost::signal<void (const VirtualEndpoint::Ptr&, const Endpoint::Ptr, const RequestMessage&)> > sig; shared_ptr<boost::signal<void (const VirtualEndpoint::Ptr&, const Endpoint::Ptr, const RequestMessage&)> > sig;
@ -62,7 +62,7 @@ void VirtualEndpoint::RegisterTopicHandler(string topic, function<void (const Vi
RegisterSubscription(topic); RegisterSubscription(topic);
} }
void VirtualEndpoint::UnregisterTopicHandler(string topic, function<void (const VirtualEndpoint::Ptr&, const Endpoint::Ptr, const RequestMessage&)> callback) void VirtualEndpoint::UnregisterTopicHandler(String topic, function<void (const VirtualEndpoint::Ptr&, const Endpoint::Ptr, const RequestMessage&)> callback)
{ {
// TODO: implement // TODO: implement
//m_TopicHandlers[method] -= callback; //m_TopicHandlers[method] -= callback;
@ -73,11 +73,11 @@ void VirtualEndpoint::UnregisterTopicHandler(string topic, function<void (const
void VirtualEndpoint::ProcessRequest(Endpoint::Ptr sender, const RequestMessage& request) void VirtualEndpoint::ProcessRequest(Endpoint::Ptr sender, const RequestMessage& request)
{ {
string method; String method;
if (!request.GetMethod(&method)) if (!request.GetMethod(&method))
return; return;
map<string, shared_ptr<boost::signal<void (const VirtualEndpoint::Ptr&, const Endpoint::Ptr, const RequestMessage&)> > >::iterator it; map<String, shared_ptr<boost::signal<void (const VirtualEndpoint::Ptr&, const Endpoint::Ptr, const RequestMessage&)> > >::iterator it;
it = m_TopicHandlers.find(method); it = m_TopicHandlers.find(method);
if (it == m_TopicHandlers.end()) if (it == m_TopicHandlers.end())

View File

@ -34,11 +34,11 @@ public:
typedef shared_ptr<VirtualEndpoint> Ptr; typedef shared_ptr<VirtualEndpoint> Ptr;
typedef weak_ptr<VirtualEndpoint> WeakPtr; typedef weak_ptr<VirtualEndpoint> WeakPtr;
void RegisterTopicHandler(string topic, function<void (const VirtualEndpoint::Ptr&, const Endpoint::Ptr, const RequestMessage&)> callback); void RegisterTopicHandler(String topic, function<void (const VirtualEndpoint::Ptr&, const Endpoint::Ptr, const RequestMessage&)> callback);
void UnregisterTopicHandler(string topic, function<void (const VirtualEndpoint::Ptr&, const Endpoint::Ptr, const RequestMessage&)> callback); void UnregisterTopicHandler(String topic, function<void (const VirtualEndpoint::Ptr&, const Endpoint::Ptr, const RequestMessage&)> callback);
virtual string GetIdentity(void) const; virtual String GetIdentity(void) const;
virtual string GetAddress(void) const; virtual String GetAddress(void) const;
virtual bool IsLocal(void) const; virtual bool IsLocal(void) const;
virtual bool IsConnected(void) const; virtual bool IsConnected(void) const;
@ -49,7 +49,7 @@ public:
virtual void Stop(void); virtual void Stop(void);
private: private:
map< string, shared_ptr<boost::signal<void (const VirtualEndpoint::Ptr&, const Endpoint::Ptr, const RequestMessage&)> > > m_TopicHandlers; map< String, shared_ptr<boost::signal<void (const VirtualEndpoint::Ptr&, const Endpoint::Ptr, const RequestMessage&)> > > m_TopicHandlers;
}; };
} }

View File

@ -40,8 +40,8 @@ JsonRpcClient::JsonRpcClient(TcpClientRole role, shared_ptr<SSL_CTX> sslContext)
*/ */
void JsonRpcClient::SendMessage(const MessagePart& message) void JsonRpcClient::SendMessage(const MessagePart& message)
{ {
Variant value = message.GetDictionary(); Value value = message.GetDictionary();
Netstring::WriteStringToIOQueue(this, value.Serialize()); NetString::WriteStringToIOQueue(this, value.Serialize());
} }
/** /**
@ -49,18 +49,18 @@ void JsonRpcClient::SendMessage(const MessagePart& message)
*/ */
void JsonRpcClient::DataAvailableHandler(void) void JsonRpcClient::DataAvailableHandler(void)
{ {
string jsonString; String jsonString;
while (Netstring::ReadStringFromIOQueue(this, &jsonString)) { while (NetString::ReadStringFromIOQueue(this, &jsonString)) {
try { try {
Variant value = Variant::Deserialize(jsonString); Value value = Value::Deserialize(jsonString);
if (!value.IsObjectType<Dictionary>()) if (!value.IsObjectType<Dictionary>())
throw_exception(invalid_argument("JSON-RPC message must be a dictionary.")); throw_exception(invalid_argument("JSON-RPC message must be a dictionary."));
OnNewMessage(GetSelf(), MessagePart(value)); OnNewMessage(GetSelf(), MessagePart(value));
} catch (const exception& ex) { } catch (const exception& ex) {
Logger::Write(LogCritical, "jsonrpc", "Exception while processing message from JSON-RPC client: " + string(ex.what())); Logger::Write(LogCritical, "jsonrpc", "Exception while processing message from JSON-RPC client: " + String(ex.what()));
} }
} }
} }

View File

@ -66,12 +66,16 @@ Dictionary::Ptr MessagePart::GetDictionary(void) const
* @param[out] The value. * @param[out] The value.
* @returns true if the value was retrieved, false otherwise. * @returns true if the value was retrieved, false otherwise.
*/ */
bool MessagePart::Get(string key, MessagePart *value) const bool MessagePart::Get(String key, MessagePart *value) const
{ {
Dictionary::Ptr dictionary; Value v;
if (!GetDictionary()->Get(key, &dictionary)) v = GetDictionary()->Get(key);
if (!v.IsObjectType<Dictionary>())
return false; return false;
Dictionary::Ptr dictionary = v;
*value = MessagePart(dictionary); *value = MessagePart(dictionary);
return true; return true;
} }
@ -82,7 +86,7 @@ bool MessagePart::Get(string key, MessagePart *value) const
* @param key The name of the property. * @param key The name of the property.
* @param value The value. * @param value The value.
*/ */
void MessagePart::Set(string key, const MessagePart& value) void MessagePart::Set(String key, const MessagePart& value)
{ {
GetDictionary()->Set(key, value.GetDictionary()); GetDictionary()->Set(key, value.GetDictionary());
} }
@ -125,7 +129,7 @@ Dictionary::Iterator MessagePart::End(void)
* @param key The name of the element. * @param key The name of the element.
* @returns true if the message contains the element, false otherwise. * @returns true if the message contains the element, false otherwise.
*/ */
bool MessagePart::Contains(const string& key) const bool MessagePart::Contains(const String& key) const
{ {
return GetDictionary()->Contains(key); return GetDictionary()->Contains(key);
} }

View File

@ -49,9 +49,15 @@ public:
* @returns true if the value was retrieved, false otherwise. * @returns true if the value was retrieved, false otherwise.
*/ */
template<typename T> template<typename T>
bool Get(string key, T *value) const bool Get(String key, T *value) const
{ {
return GetDictionary()->Get(key, value); Value v =GetDictionary()->Get(key);
if (v.IsEmpty())
return false;
*value = static_cast<T>(v);
return true;
} }
/** /**
@ -61,13 +67,13 @@ public:
* @param value The value. * @param value The value.
*/ */
template<typename T> template<typename T>
void Set(string key, const T& value) void Set(String key, const T& value)
{ {
GetDictionary()->Set(key, value); GetDictionary()->Set(key, value);
} }
bool Get(string key, MessagePart *value) const; bool Get(String key, MessagePart *value) const;
void Set(string key, const MessagePart& value); void Set(String key, const MessagePart& value);
/** /**
* Adds an item to the message using an automatically generated property name. * Adds an item to the message using an automatically generated property name.
@ -82,7 +88,7 @@ public:
void Add(const MessagePart& value); void Add(const MessagePart& value);
bool Contains(const string& key) const; bool Contains(const String& key) const;
Dictionary::Iterator Begin(void); Dictionary::Iterator Begin(void);
Dictionary::Iterator End(void); Dictionary::Iterator End(void);

View File

@ -51,7 +51,7 @@ public:
* @param[out] value The value. * @param[out] value The value.
* @returns true if the value was retrieved, false otherwise. * @returns true if the value was retrieved, false otherwise.
*/ */
inline bool GetVersion(string *value) const inline bool GetVersion(String *value) const
{ {
return Get("jsonrpc", value); return Get("jsonrpc", value);
} }
@ -61,7 +61,7 @@ public:
* *
* @param value The version. * @param value The version.
*/ */
inline void SetVersion(const string& value) inline void SetVersion(const String& value)
{ {
Set("jsonrpc", value); Set("jsonrpc", value);
} }
@ -72,7 +72,7 @@ public:
* @param[out] value The method. * @param[out] value The method.
* @returns true if the value was retrieved, false otherwise. * @returns true if the value was retrieved, false otherwise.
*/ */
inline bool GetMethod(string *value) const inline bool GetMethod(String *value) const
{ {
return Get("method", value); return Get("method", value);
} }
@ -82,7 +82,7 @@ public:
* *
* @param value The method. * @param value The method.
*/ */
inline void SetMethod(const string& value) inline void SetMethod(const String& value)
{ {
Set("method", value); Set("method", value);
} }
@ -114,7 +114,7 @@ public:
* @param[out] value The ID. * @param[out] value The ID.
* @return true if the value was retrieved, false otherwise. * @return true if the value was retrieved, false otherwise.
*/ */
inline bool GetID(string *value) const inline bool GetID(String *value) const
{ {
return Get("id", value); return Get("id", value);
} }
@ -124,7 +124,7 @@ public:
* *
* @param value The ID. * @param value The ID.
*/ */
inline void SetID(const string& value) inline void SetID(const String& value)
{ {
Set("id", value); Set("id", value);
} }

Some files were not shown because too many files have changed in this diff Show More