diff --git a/base/Makefile.am b/base/Makefile.am index 9b5d72b57..8a8c3810f 100644 --- a/base/Makefile.am +++ b/base/Makefile.am @@ -30,6 +30,8 @@ libbase_la_SOURCES = \ object.h \ process.cpp \ process.h \ + qstring.cpp \ + qstring.h \ ringbuffer.cpp \ ringbuffer.h \ scriptfunction.cpp \ @@ -58,8 +60,8 @@ libbase_la_SOURCES = \ unix.h \ utility.cpp \ utility.h \ - variant.cpp \ - variant.h \ + value.cpp \ + value.h \ win32.cpp \ win32.h diff --git a/base/application.cpp b/base/application.cpp index 7d7147246..c841110d6 100644 --- a/base/application.cpp +++ b/base/application.cpp @@ -91,6 +91,9 @@ void Application::RunEventLoop(void) break; 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. */ -string Application::GetExePath(void) const +String Application::GetExePath(void) const { - static string result; + static String result; - if (!result.empty()) + if (!result.IsEmpty()) return result; - string executablePath; + String executablePath; #ifndef _WIN32 - string argv0 = m_Arguments[0]; + String argv0 = m_Arguments[0]; char buffer[MAXPATHLEN]; if (getcwd(buffer, sizeof(buffer)) == NULL) throw_exception(PosixException("getcwd failed", errno)); - string workingDirectory = buffer; + String workingDirectory = buffer; if (argv0[0] != '/') executablePath = workingDirectory + "/" + argv0; else 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"); if (pathEnv != NULL) { - vector paths; + vector paths; boost::algorithm::split(paths, pathEnv, boost::is_any_of(":")); bool foundPath = false; - BOOST_FOREACH(string& path, paths) { - string pathTest = path + "/" + argv0; + BOOST_FOREACH(String& path, paths) { + String pathTest = path + "/" + argv0; - if (access(pathTest.c_str(), X_OK) == 0) { + if (access(pathTest.CStr(), X_OK) == 0) { executablePath = pathTest; foundPath = true; break; @@ -148,13 +159,13 @@ string Application::GetExePath(void) const } if (!foundPath) { - executablePath.clear(); + executablePath.Clear(); 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)); result = buffer; @@ -258,7 +269,9 @@ int Application::Run(int argc, char **argv) m_Arguments.clear(); 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()) { result = Main(m_Arguments); @@ -272,22 +285,24 @@ int Application::Run(int argc, char **argv) Logger::Write(LogCritical, "base", "---"); 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; } } + DynamicObject::FinishTx(); + return result; } -void Application::UpdatePidFile(const string& filename) +void Application::UpdatePidFile(const String& filename) { ClosePidFile(); /* There's just no sane way of getting a file descriptor for a * 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) throw_exception(runtime_error("Could not open PID file '" + filename + "'")); diff --git a/base/application.h b/base/application.h index 664879aa8..8288dde17 100644 --- a/base/application.h +++ b/base/application.h @@ -41,7 +41,7 @@ public: int Run(int argc, char **argv); - virtual int Main(const vector& args) = 0; + virtual int Main(const vector& args) = 0; static void Shutdown(void); @@ -49,19 +49,19 @@ public: static bool IsMainThread(void); - void UpdatePidFile(const string& filename); + void UpdatePidFile(const String& filename); void ClosePidFile(void); protected: void RunEventLoop(void); - string GetExePath(void) const; + String GetExePath(void) const; private: static Application::Ptr m_Instance; /**< The application instance. */ static bool m_ShuttingDown; /**< Whether the application is in the process of shutting down. */ - vector m_Arguments; /**< Command-line arguments */ + vector m_Arguments; /**< Command-line arguments */ FILE *m_PidFile; /**< The PID file */ static bool m_Debugging; /**< Whether debugging is enabled. */ static boost::thread::id m_MainThreadID; /**< ID of the main thread. */ diff --git a/base/base.vcxproj b/base/base.vcxproj index 8545cbd00..50f17fab1 100644 --- a/base/base.vcxproj +++ b/base/base.vcxproj @@ -26,6 +26,7 @@ + @@ -40,7 +41,7 @@ - + @@ -53,6 +54,7 @@ + @@ -72,7 +74,7 @@ - + diff --git a/base/base.vcxproj.filters b/base/base.vcxproj.filters index 2fd084fd5..d059aaefc 100644 --- a/base/base.vcxproj.filters +++ b/base/base.vcxproj.filters @@ -49,9 +49,6 @@ Quelldateien - - Quelldateien - Quelldateien @@ -85,6 +82,12 @@ Quelldateien + + Quelldateien + + + Quelldateien + @@ -141,9 +144,6 @@ Headerdateien - - Headerdateien - Headerdateien @@ -177,6 +177,12 @@ Headerdateien + + Headerdateien + + + Headerdateien + diff --git a/base/component.cpp b/base/component.cpp index 55c1c26f4..fbdc68a69 100644 --- a/base/component.cpp +++ b/base/component.cpp @@ -34,7 +34,7 @@ Component::Component(const Dictionary::Ptr& properties) if (!IsLocal()) throw_exception(runtime_error("Component objects must be local.")); - string path; + String path; #ifdef _WIN32 path = GetName() + ".dll"; #else /* _WIN32 */ @@ -44,12 +44,12 @@ Component::Component(const Dictionary::Ptr& properties) Logger::Write(LogInformation, "base", "Loading component '" + GetName() + "' (using library '" + path + "')"); #ifdef _WIN32 - HMODULE hModule = LoadLibrary(path.c_str()); + HMODULE hModule = LoadLibrary(path.CStr()); if (hModule == NULL) throw_exception(Win32Exception("LoadLibrary('" + path + "') failed", GetLastError())); #else /* _WIN32 */ - lt_dlhandle hModule = lt_dlopen(path.c_str()); + lt_dlhandle hModule = lt_dlopen(path.CStr()); if (hModule == NULL) { 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; - SetImplementation(impl); - impl->Start(); + m_Impl = impl; } Component::~Component(void) { - IComponent::Ptr impl = GetImplementation(); - - 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); + if (m_Impl) + m_Impl->Stop(); } /** @@ -122,12 +107,12 @@ void Component::SetImplementation(const IComponent::Ptr& impl) * * @param componentDirectory The directory. */ -void Component::AddSearchDir(const string& componentDirectory) +void Component::AddSearchDir(const String& componentDirectory) { #ifdef _WIN32 - SetDllDirectory(componentDirectory.c_str()); + SetDllDirectory(componentDirectory.CStr()); #else /* _WIN32 */ - lt_dladdsearchdir(componentDirectory.c_str()); + lt_dladdsearchdir(componentDirectory.CStr()); #endif /* _WIN32 */ } diff --git a/base/component.h b/base/component.h index 2f7f9c25f..ce6f6d3b0 100644 --- a/base/component.h +++ b/base/component.h @@ -56,11 +56,10 @@ public: Component(const Dictionary::Ptr& properties); ~Component(void); - static void AddSearchDir(const string& componentDirectory); + static void AddSearchDir(const String& componentDirectory); private: - IComponent::Ptr GetImplementation(void) const; - void SetImplementation(const IComponent::Ptr& impl); + IComponent::Ptr m_Impl; }; typedef IComponent *(*CreateComponentFunction)(void); diff --git a/base/dictionary.cpp b/base/dictionary.cpp index 4864c1810..986e3d70a 100644 --- a/base/dictionary.cpp +++ b/base/dictionary.cpp @@ -22,6 +22,68 @@ 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::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::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. * @@ -58,7 +120,7 @@ long Dictionary::GetLength(void) const * @param key The key. * @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()); } @@ -68,7 +130,7 @@ bool Dictionary::Contains(const string& key) const * * @param key The key. */ -void Dictionary::Remove(const string& key) +void Dictionary::Remove(const String& key) { Dictionary::Iterator it; it = m_Data.find(key); @@ -77,6 +139,21 @@ void Dictionary::Remove(const string& key) return; 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.")); 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; @@ -111,10 +188,10 @@ cJSON *Dictionary::ToJson(void) const cJSON *json = cJSON_CreateObject(); try { - string key; - Variant value; + String key; + Value value; BOOST_FOREACH(tie(key, value), m_Data) { - cJSON_AddItemToObject(json, key.c_str(), value.ToJson()); + cJSON_AddItemToObject(json, key.CStr(), value.ToJson()); } } catch (...) { cJSON_Delete(json); @@ -123,3 +200,6 @@ cJSON *Dictionary::ToJson(void) const return json; } + +void Dictionary::OnItemModified(const String& key, const Value& value) +{ } diff --git a/base/dictionary.h b/base/dictionary.h index 9c0e5d760..6dc8b2115 100644 --- a/base/dictionary.h +++ b/base/dictionary.h @@ -34,82 +34,28 @@ public: typedef shared_ptr Ptr; typedef weak_ptr WeakPtr; - typedef map::iterator Iterator; + typedef map::iterator Iterator; - /** - * Retrieves a value from the dictionary. - * - * @param key The key. - * @param[out] value Pointer to the value. - * @returns true if the value was retrieved, false otherwise. - */ - template - bool Get(const string& key, T *value) const - { - map::const_iterator i = m_Data.find(key); - - if (i == m_Data.end()) - return false; - - *value = static_cast(i->second); - - return true; - } - - /** - * Sets a value in the dictionary. - * - * @param key The key. - * @param value The value. - */ - template - void Set(const string& key, const T& value) - { - pair::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 - 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; + Value Get(const String& key) const; + void Set(const String& key, const Value& value); + String Add(const Value& value); + bool Contains(const String& key) const; Iterator Begin(void); Iterator End(void); long GetLength(void) const; - void Remove(const string& key); + void Remove(const String& key); + void Remove(Iterator it); static Dictionary::Ptr FromJson(cJSON *json); cJSON *ToJson(void) const; + virtual void OnItemModified(const String& key, const Value& value); + private: - map m_Data; + map m_Data; }; inline Dictionary::Iterator range_begin(Dictionary::Ptr x) diff --git a/base/dynamicobject.cpp b/base/dynamicobject.cpp index 44adff2e6..0f3a72d33 100644 --- a/base/dynamicobject.cpp +++ b/base/dynamicobject.cpp @@ -21,95 +21,267 @@ using namespace icinga; -map, Dictionary::Ptr> DynamicObject::m_PersistentTags; -boost::signal DynamicObject::OnCommitted; -boost::signal DynamicObject::OnRemoved; +map, Dictionary::Ptr> DynamicObject::m_PersistentUpdates; +double DynamicObject::m_CurrentTx = 0; +set DynamicObject::m_ModifiedObjects; -DynamicObject::DynamicObject(const Dictionary::Ptr& properties) - : m_Properties(properties), m_Tags(boost::make_shared()) +boost::signal DynamicObject::OnAttributeChanged; +boost::signal DynamicObject::OnRegistered; +boost::signal DynamicObject::OnUnregistered; +boost::signal&)> DynamicObject::OnTransactionClosing; + +DynamicObject::DynamicObject(const Dictionary::Ptr& serializedObject) + : m_ConfigTx(0) { - /* restore the object's tags */ - map, Dictionary::Ptr>::iterator it; - it = m_PersistentTags.find(make_pair(GetType(), GetName())); - if (it != m_PersistentTags.end()) { - m_Tags = it->second; - m_PersistentTags.erase(it); + RegisterAttribute("__name", Attribute_Config); + RegisterAttribute("__type", Attribute_Config); + RegisterAttribute("__local", Attribute_Config); + RegisterAttribute("__abstract", Attribute_Config); + RegisterAttribute("__source", Attribute_Local); + RegisterAttribute("methods", Attribute_Config); + + /* apply state from the config item/remote update */ + ApplyUpdate(serializedObject, true); + + /* restore the object's persistent state */ + map, 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(); + + 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(); + 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(); + 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()) + 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(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()) + 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 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; - GetProperties()->Get("__type", &type); + InternalSetAttribute(name, data, GetCurrentTx()); +} + +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 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; } -string DynamicObject::GetName(void) const +String DynamicObject::GetName(void) const { - string name; - GetProperties()->Get("__name", &name); + String name; + GetAttribute("__name", &name); return name; } bool DynamicObject::IsLocal(void) const { - bool value = false; - GetProperties()->Get("__local", &value); - return value; + long local = 0; + GetAttribute("__local", &local); + return (local != 0); } bool DynamicObject::IsAbstract(void) const { - bool value = false; - GetProperties()->Get("__abstract", &value); - return value; + long abstract = 0; + GetAttribute("__abstract", &abstract); + 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; - GetProperties()->Get("__source", &value); - return value; + String source; + GetAttribute("__source", &source); + return source; } -void DynamicObject::SetCommitTimestamp(double ts) -{ - GetProperties()->Set("__tx", ts); -} - -double DynamicObject::GetCommitTimestamp(void) const -{ - double value = 0; - GetProperties()->Get("__tx", &value); - return value; -} - -void DynamicObject::Commit(void) +void DynamicObject::Register(void) { assert(Application::IsMainThread()); @@ -121,9 +293,7 @@ void DynamicObject::Commit(void) ti = GetAllObjects().insert(make_pair(GetType(), DynamicObject::NameMap())); ti.first->second.insert(make_pair(GetName(), GetSelf())); - SetCommitTimestamp(Utility::GetTime()); - - OnCommitted(GetSelf()); + OnRegistered(GetSelf()); } void DynamicObject::Unregister(void) @@ -143,10 +313,10 @@ void DynamicObject::Unregister(void) 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; tt = GetAllObjects().find(type); @@ -167,7 +337,7 @@ pair Dynamic return make_pair(GetAllObjects().begin(), GetAllObjects().end()); } -pair DynamicObject::GetObjects(const string& type) +pair DynamicObject::GetObjects(const String& type) { pair ti; ti = GetAllObjects().insert(make_pair(type, DynamicObject::NameMap())); @@ -175,19 +345,15 @@ pair Dynamic return make_pair(ti.first->second.begin(), ti.first->second.end()); } -void DynamicObject::RemoveTag(const string& key) -{ - GetTags()->Remove(key); -} - -ScriptTask::Ptr DynamicObject::InvokeMethod(const string& method, - const vector& arguments, ScriptTask::CompletionCallback callback) +ScriptTask::Ptr DynamicObject::InvokeMethod(const String& method, + const vector& arguments, ScriptTask::CompletionCallback callback) { Dictionary::Ptr methods; - string funcName; - if (!GetProperty("methods", &methods) || !methods->Get(method, &funcName)) + if (!GetAttribute("methods", &methods) || !methods->Contains(method)) return ScriptTask::Ptr(); + String funcName = methods->Get(method); + ScriptFunction::Ptr func = ScriptFunction::GetByName(funcName); if (!func) @@ -199,12 +365,12 @@ ScriptTask::Ptr DynamicObject::InvokeMethod(const string& method, return task; } -void DynamicObject::DumpObjects(const string& filename) +void DynamicObject::DumpObjects(const String& filename) { Logger::Write(LogInformation, "base", "Dumping program state to file '" + filename + "'"); ofstream fp; - fp.open(filename.c_str()); + fp.open(filename.CStr()); if (!fp) 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("name", object->GetName()); + int types = Attribute_Replicated; + /* only persist properties for replicated objects or for objects * that are marked as persistent */ - if (!object->GetSource().empty() /*|| object->IsPersistent()*/) - persistentObject->Set("properties", object->GetProperties()); + if (!object->GetSource().IsEmpty() /*|| object->IsPersistent()*/) { + 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; - string json = value.Serialize(); + if (!update) + continue; - /* This is quite ugly, unfortunatelly Netstring requires an IOQueue object */ - Netstring::WriteStringToIOQueue(fifo.get(), json); + persistentObject->Set("update", update); + + 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; 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 + "'"); std::ifstream fp; - fp.open(filename.c_str()); + fp.open(filename.CStr()); /* TODO: Fix this horrible mess. */ FIFO::Ptr fifo = boost::make_shared(); @@ -265,36 +442,27 @@ void DynamicObject::RestoreObjects(const string& filename) fifo->Write(buffer, fp.gcount()); } - string message; - while (Netstring::ReadStringFromIOQueue(fifo.get(), &message)) { - Variant value = Variant::Deserialize(message); + String message; + while (NetString::ReadStringFromIOQueue(fifo.get(), &message)) { + Value value = Value::Deserialize(message); if (!value.IsObjectType()) throw_exception(runtime_error("JSON objects in the program state file must be dictionaries.")); Dictionary::Ptr persistentObject = value; - string type; - if (!persistentObject->Get("type", &type)) - continue; + String type = persistentObject->Get("type"); + String name = persistentObject->Get("name"); + int create = persistentObject->Get("create"); + Dictionary::Ptr update = persistentObject->Get("update"); - string name; - if (!persistentObject->Get("name", &name)) - continue; - - 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(); + if (create != 0) { + DynamicObject::Ptr object = Create(type, update); + object->Register(); } else { /* keep non-replicated objects until another config object with * 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; } -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) 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; } -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; it = GetClasses().find(type); @@ -330,3 +498,23 @@ DynamicObject::Ptr DynamicObject::Create(const string& type, const Dictionary::P else return boost::make_shared(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; +} diff --git a/base/dynamicobject.h b/base/dynamicobject.h index f61f08f08..36f4e89f6 100644 --- a/base/dynamicobject.h +++ b/base/dynamicobject.h @@ -23,6 +23,30 @@ 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. * @@ -36,84 +60,102 @@ public: typedef function Factory; - typedef map ClassMap; - typedef map NameMap; - typedef map TypeMap; + typedef map ClassMap; + typedef map NameMap; + typedef map TypeMap; - DynamicObject(const Dictionary::Ptr& properties); + typedef map AttributeMap; + typedef AttributeMap::iterator AttributeIterator; + typedef AttributeMap::const_iterator AttributeConstIterator; - void SetProperties(const Dictionary::Ptr& config); - Dictionary::Ptr GetProperties(void) const; + DynamicObject(const Dictionary::Ptr& serializedObject); + + 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 - 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(data); + return true; } - void SetTags(const Dictionary::Ptr& tags); - Dictionary::Ptr GetTags(void) const; + void ClearAttribute(const String& name); - template - void SetTag(const string& key, const T& value) - { - GetTags()->Set(key, value); - } + bool HasAttribute(const String& name) const; - template - bool GetTag(const string& key, T *value) const - { - return GetTags()->Get(key, value); - } + void ClearAttributesByType(DynamicAttributeType type); - void RemoveTag(const string& key); + AttributeConstIterator AttributeBegin(void) const; + AttributeConstIterator AttributeEnd(void) const; - ScriptTask::Ptr InvokeMethod(const string& method, - const vector& arguments, ScriptTask::CompletionCallback callback); + static boost::signal OnAttributeChanged; + static boost::signal OnRegistered; + static boost::signal OnUnregistered; + static boost::signal&)> OnTransactionClosing; - string GetType(void) const; - string GetName(void) const; + ScriptTask::Ptr InvokeMethod(const String& method, + const vector& arguments, ScriptTask::CompletionCallback callback); + + String GetType(void) const; + String GetName(void) const; bool IsLocal(void) const; bool IsAbstract(void) const; - void SetSource(const string& value); - string GetSource(void) const; + void SetSource(const String& value); + 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); - static DynamicObject::Ptr GetObject(const string& type, const string& name); + static DynamicObject::Ptr GetObject(const String& type, const String& name); static pair GetTypes(void); - static pair GetObjects(const string& type); + static pair GetObjects(const String& type); - static void DumpObjects(const string& filename); - static void RestoreObjects(const string& filename); + static void DumpObjects(const String& filename); + static void RestoreObjects(const String& filename); - static void RegisterClass(const string& type, Factory factory); - static DynamicObject::Ptr Create(const string& type, const Dictionary::Ptr& properties); + static void RegisterClass(const String& type, Factory factory); + static DynamicObject::Ptr Create(const String& type, const Dictionary::Ptr& properties); - static boost::signal OnCommitted; - static boost::signal OnRemoved; + static double GetCurrentTx(void); + static void BeginTx(void); + static void FinishTx(void); 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 TypeMap& GetAllObjects(void); - Dictionary::Ptr m_Properties; - Dictionary::Ptr m_Tags; + AttributeMap m_Attributes; + double m_ConfigTx; - static map, Dictionary::Ptr> m_PersistentTags; + static map, Dictionary::Ptr> m_PersistentUpdates; + static double m_CurrentTx; - void SetCommitTimestamp(double ts); + static set m_ModifiedObjects; }; class RegisterClassHelper { public: - RegisterClassHelper(const string& name, DynamicObject::Factory factory) + RegisterClassHelper(const String& name, DynamicObject::Factory factory) { DynamicObject::RegisterClass(name, factory); } diff --git a/base/exception.cpp b/base/exception.cpp index fbb796369..04d64edf2 100644 --- a/base/exception.cpp +++ b/base/exception.cpp @@ -46,7 +46,7 @@ void Exception::SetCode(int code) * * @returns The description. */ -string Exception::GetMessage(void) const +String Exception::GetMessage(void) const { return m_Message; } @@ -58,7 +58,7 @@ string Exception::GetMessage(void) const */ 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. */ -void Exception::SetMessage(string message) +void Exception::SetMessage(String message) { m_Message = message; } @@ -76,19 +76,19 @@ void Exception::SetMessage(string message) * Formats an Win32 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; - string result = "Unknown error."; + String result = "Unknown error."; DWORD rc = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, code, 0, (char *)&message, 0, NULL); if (rc != 0) { - result = string(message); + result = String(message); LocalFree(message); /* remove trailing new-line characters */ @@ -103,9 +103,9 @@ string Win32Exception::FormatErrorCode(int code) * Formats a Posix 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); } @@ -114,9 +114,9 @@ string PosixException::FormatErrorCode(int code) * Formats an OpenSSL 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); diff --git a/base/exception.h b/base/exception.h index 8d041560a..1e5bd19c5 100644 --- a/base/exception.h +++ b/base/exception.h @@ -35,11 +35,11 @@ public: : m_Message(), m_Code(0) { } - Exception(string message) + Exception(String message) : m_Message(message), m_Code(0) { } - Exception(string message, int code) + Exception(String message, int code) : m_Message(message), m_Code(code) { } @@ -50,16 +50,16 @@ public: { } int GetCode(void) const; - string GetMessage(void) const; + String GetMessage(void) const; virtual const char *what(void) const throw(); protected: void SetCode(int code); - void SetMessage(string message); + void SetMessage(String message); private: - string m_Message; + String m_Message; int m_Code; }; @@ -70,7 +70,7 @@ private: inline klass(void) : Exception() \ { } \ \ - inline klass(string message) \ + inline klass(String message) \ : Exception(message) \ { } \ } @@ -96,17 +96,17 @@ public: * @param message An error message. * @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) { } /** - * Returns a string that describes the Win32 error. + * Returns a String that describes the Win32 error. * * @param code The Win32 error code. * @returns A description of the error. */ - static string FormatErrorCode(int code); + static String FormatErrorCode(int code); }; #endif /* _WIN32 */ @@ -122,17 +122,17 @@ public: * @param message An error message. * @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) { } /** - * Returns a string that describes the Posix error. + * Returns a String that describes the Posix error. * * @param code The Posix error code. * @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 errorCode An OpenSSL error code. */ - inline OpenSSLException(const string& message, int errorCode) + inline OpenSSLException(const String& message, int 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. * @returns A description of the error. */ - static string FormatErrorCode(int code); + static String FormatErrorCode(int code); }; } diff --git a/base/i2-base.h b/base/i2-base.h index 62b96d935..2d96f1062 100644 --- a/base/i2-base.h +++ b/base/i2-base.h @@ -90,7 +90,6 @@ #include #include -using std::string; using std::vector; using std::map; using std::list; @@ -98,6 +97,7 @@ using std::set; using std::multimap; using std::pair; using std::deque; +using std::make_pair; using std::stringstream; using std::istream; @@ -164,11 +164,12 @@ namespace tuples = boost::tuples; # define I2_BASE_API I2_IMPORT #endif /* I2_BASE_BUILD */ +#include "qstring.h" #include "utility.h" #include "object.h" #include "exception.h" #include "event.h" -#include "variant.h" +#include "value.h" #include "dictionary.h" #include "ringbuffer.h" #include "timer.h" diff --git a/base/logger.cpp b/base/logger.cpp index 56718b9f6..f3dea58cc 100644 --- a/base/logger.cpp +++ b/base/logger.cpp @@ -32,11 +32,15 @@ REGISTER_CLASS(Logger); Logger::Logger(const Dictionary::Ptr& properties) : DynamicObject(properties) { + RegisterAttribute("type", Attribute_Config); + RegisterAttribute("path", Attribute_Config); + RegisterAttribute("severity", Attribute_Config); + if (!IsLocal()) throw_exception(runtime_error("Logger objects must be local.")); - string type; - if (!GetProperty("type", &type)) + String type; + if (!GetAttribute("type", &type)) throw_exception(runtime_error("Logger objects must have a 'type' property.")); ILogger::Ptr impl; @@ -48,8 +52,8 @@ Logger::Logger(const Dictionary::Ptr& properties) throw_exception(invalid_argument("Syslog is not supported on Windows.")); #endif /* _WIN32 */ } else if (type == "file") { - string path; - if (!GetProperty("path", &path)) + String path; + if (!GetAttribute("path", &path)) throw_exception(invalid_argument("'log' object of type 'file' must have a 'path' property")); StreamLogger::Ptr slogger = boost::make_shared(); @@ -63,7 +67,7 @@ Logger::Logger(const Dictionary::Ptr& properties) } 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 message The message. */ -void Logger::Write(LogSeverity severity, const string& facility, - const string& message) +void Logger::Write(LogSeverity severity, const String& facility, + const String& message) { LogEntry entry; entry.Timestamp = Utility::GetTime(); @@ -92,12 +96,9 @@ void Logger::Write(LogSeverity severity, const string& facility, */ LogSeverity Logger::GetMinSeverity(void) const { - string strSeverity; - LogSeverity severity = LogInformation; - if (GetProperty("severity", &strSeverity)) - severity = Logger::StringToSeverity(strSeverity); - - return severity; + String strSeverity = "information"; + GetAttribute("severity", &strSeverity); + return Logger::StringToSeverity(strSeverity); } /** @@ -112,23 +113,11 @@ void Logger::ForwardLogEntry(const LogEntry& entry) Logger::Ptr logger = dynamic_pointer_cast(object); if (entry.Severity >= logger->GetMinSeverity()) - logger->GetImplementation()->ProcessLogEntry(entry); + logger->m_Impl->ProcessLogEntry(entry); } } -ILogger::Ptr Logger::GetImplementation(void) const -{ - ILogger::Ptr impl; - GetTag("impl", &impl); - return impl; -} - -void Logger::SetImplementation(const ILogger::Ptr& impl) -{ - SetTag("impl", impl); -} - -string Logger::SeverityToString(LogSeverity severity) +String Logger::SeverityToString(LogSeverity severity) { switch (severity) { 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") return LogDebug; diff --git a/base/logger.h b/base/logger.h index 524bc8d21..49a61863d 100644 --- a/base/logger.h +++ b/base/logger.h @@ -44,8 +44,8 @@ enum LogSeverity struct LogEntry { double Timestamp; LogSeverity Severity; - string Facility; - string Message; + String Facility; + String Message; }; /** @@ -76,19 +76,17 @@ public: Logger(const Dictionary::Ptr& properties); - static void Write(LogSeverity severity, const string& facility, - const string& message); + static void Write(LogSeverity severity, const String& facility, + const String& message); - static string SeverityToString(LogSeverity severity); - static LogSeverity StringToSeverity(const string& severity); + static String SeverityToString(LogSeverity severity); + static LogSeverity StringToSeverity(const String& severity); LogSeverity GetMinSeverity(void) const; private: LogSeverity m_MinSeverity; - - ILogger::Ptr GetImplementation(void) const; - void SetImplementation(const ILogger::Ptr& impl); + ILogger::Ptr m_Impl; static void ForwardLogEntry(const LogEntry& entry); }; diff --git a/base/netstring.cpp b/base/netstring.cpp index 9f09b7f78..f15c73f36 100644 --- a/base/netstring.cpp +++ b/base/netstring.cpp @@ -22,19 +22,19 @@ 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[out] str The string that has been read from the FIFO. - * @returns true if a complete string was read from the FIFO, false otherwise. + * @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. * @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(); - /* minimum netstring length is 3 */ + /* minimum netString length is 3 */ if (buffer_length < 3) return false; @@ -52,7 +52,7 @@ bool Netstring::ReadStringFromIOQueue(IOQueue *queue, string *str) /* no leading zeros allowed */ if (buffer[0] == '0' && isdigit(buffer[1])) { free(buffer); - throw_exception(invalid_argument("Invalid netstring (leading zero)")); + throw_exception(invalid_argument("Invalid netString (leading zero)")); } size_t len, i; @@ -91,16 +91,16 @@ bool Netstring::ReadStringFromIOQueue(IOQueue *queue, string *str) /* check for the colon delimiter */ if (buffer[i] != ':') { 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] != ',') { 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); @@ -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 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; - prefixbuf << str.size() << ":"; + prefixbuf << str.GetLength() << ":"; - string prefix = prefixbuf.str(); - queue->Write(prefix.c_str(), prefix.size()); - queue->Write(str.c_str(), str.size()); + String prefix = prefixbuf.str(); + queue->Write(prefix.CStr(), prefix.GetLength()); + queue->Write(str.CStr(), str.GetLength()); queue->Write(",", 1); } diff --git a/base/netstring.h b/base/netstring.h index 35d5b8681..3688ae33c 100644 --- a/base/netstring.h +++ b/base/netstring.h @@ -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 */ -class I2_BASE_API Netstring +class I2_BASE_API NetString { public: - static bool ReadStringFromIOQueue(IOQueue *queue, string *message); - static void WriteStringToIOQueue(IOQueue *queue, const string& message); + static bool ReadStringFromIOQueue(IOQueue *queue, String *message); + static void WriteStringToIOQueue(IOQueue *queue, const String& message); private: - Netstring(void); + NetString(void); }; } diff --git a/base/process.cpp b/base/process.cpp index a1b8f43e4..01598b094 100644 --- a/base/process.cpp +++ b/base/process.cpp @@ -30,7 +30,7 @@ boost::mutex Process::m_Mutex; deque Process::m_Tasks; condition_variable Process::m_TasksCV; -Process::Process(const string& command) +Process::Process(const String& command) : AsyncTask(), m_Command(command), m_UsePopen(false) { if (!m_ThreadCreated) { @@ -133,12 +133,12 @@ void Process::InitTask(void) m_Result.ExecutionStart = Utility::GetTime(); #ifdef _MSC_VER - m_FP = _popen(m_Command.c_str(), "r"); + m_FP = _popen(m_Command.CStr(), "r"); #else /* _MSC_VER */ if (!m_UsePopen) { 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); if (m_FP == NULL) @@ -146,7 +146,7 @@ void Process::InitTask(void) } if (m_UsePopen) - m_FP = popen(m_Command.c_str(), "r"); + m_FP = popen(m_Command.CStr(), "r"); #endif /* _MSC_VER */ if (m_FP == NULL) @@ -164,7 +164,7 @@ bool Process::RunTask(void) if (!feof(m_FP)) return true; - string output = m_OutputStream.str(); + String output = m_OutputStream.str(); int status, exitcode; #ifdef _MSC_VER @@ -189,7 +189,7 @@ bool Process::RunTask(void) /* cmd.exe returns error code 1 (warning) when the plugin * could not be executed - change the exit status to "unknown" * when we have no plugin output. */ - if (output.empty()) + if (output.IsEmpty()) exitcode = 128; #endif /* _MSC_VER */ diff --git a/base/process.h b/base/process.h index e04b885ac..b4bc5cc9b 100644 --- a/base/process.h +++ b/base/process.h @@ -28,7 +28,7 @@ struct ProcessResult double ExecutionStart; double ExecutionEnd; long ExitStatus; - string Output; + String Output; }; class I2_BASE_API Process : public AsyncTask @@ -39,12 +39,12 @@ public: static const int MaxTasksPerThread = 128; - Process(const string& command); + Process(const String& command); private: static bool m_ThreadCreated; - string m_Command; + String m_Command; FILE *m_FP; stringstream m_OutputStream; diff --git a/base/qstring.cpp b/base/qstring.cpp new file mode 100644 index 000000000..6a511842a --- /dev/null +++ b/base/qstring.cpp @@ -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(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(lhs) + static_cast(rhs); +} + +String icinga::operator+(const String& lhs, const char *rhs) +{ + return static_cast(lhs) + rhs; +} + +String icinga::operator+(const char *lhs, const String& rhs) +{ + return lhs + static_cast(rhs); +} + +bool icinga::operator==(const String& lhs, const String& rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +bool icinga::operator==(const String& lhs, const char *rhs) +{ + return static_cast(lhs) == rhs; +} + +bool icinga::operator==(const char *lhs, const String& rhs) +{ + return lhs == static_cast(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(); +} + diff --git a/base/qstring.h b/base/qstring.h new file mode 100644 index 000000000..cfb6e89d0 --- /dev/null +++ b/base/qstring.h @@ -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 + 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 + vector Split(const Predicate& predicate) + { + vector 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 +{ + typedef icinga::String::Iterator type; +}; + +template<> +struct range_const_iterator +{ + typedef icinga::String::ConstIterator type; +}; + +} + +#endif /* STRING_H */ diff --git a/base/scriptfunction.cpp b/base/scriptfunction.cpp index 683736c86..53b02ac04 100644 --- a/base/scriptfunction.cpp +++ b/base/scriptfunction.cpp @@ -2,25 +2,25 @@ using namespace icinga; -map ScriptFunction::m_Functions; +map ScriptFunction::m_Functions; ScriptFunction::ScriptFunction(const 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; } -void ScriptFunction::Unregister(const string& name) +void ScriptFunction::Unregister(const String& name) { m_Functions.erase(name); } -ScriptFunction::Ptr ScriptFunction::GetByName(const string& name) +ScriptFunction::Ptr ScriptFunction::GetByName(const String& name) { - map::iterator it; + map::iterator it; it = m_Functions.find(name); @@ -30,7 +30,7 @@ ScriptFunction::Ptr ScriptFunction::GetByName(const string& name) return it->second; } -void ScriptFunction::Invoke(const ScriptTask::Ptr& task, const vector& arguments) +void ScriptFunction::Invoke(const ScriptTask::Ptr& task, const vector& arguments) { m_Callback(task, arguments); } diff --git a/base/scriptfunction.h b/base/scriptfunction.h index 985922b76..da348c386 100644 --- a/base/scriptfunction.h +++ b/base/scriptfunction.h @@ -31,20 +31,20 @@ public: typedef shared_ptr Ptr; typedef weak_ptr WeakPtr; - typedef function&, const vector& arguments)> Callback; + typedef function&, const vector& arguments)> Callback; ScriptFunction(const Callback& function); - static void Register(const string& name, const ScriptFunction::Ptr& function); - static void Unregister(const string& name); - static ScriptFunction::Ptr GetByName(const string& name); + static void Register(const String& name, const ScriptFunction::Ptr& function); + static void Unregister(const String& name); + static ScriptFunction::Ptr GetByName(const String& name); - void Invoke(const shared_ptr& task, const vector& arguments); + void Invoke(const shared_ptr& task, const vector& arguments); private: Callback m_Callback; - static map m_Functions; + static map m_Functions; }; } diff --git a/base/scripttask.cpp b/base/scripttask.cpp index ac9e87814..ff3ff3134 100644 --- a/base/scripttask.cpp +++ b/base/scripttask.cpp @@ -2,8 +2,8 @@ using namespace icinga; -ScriptTask::ScriptTask(const ScriptFunction::Ptr& function, const vector& arguments) - : AsyncTask(), m_Function(function), m_Arguments(arguments) +ScriptTask::ScriptTask(const ScriptFunction::Ptr& function, const vector& arguments) + : AsyncTask(), m_Function(function), m_Arguments(arguments) { } void ScriptTask::Run(void) diff --git a/base/scripttask.h b/base/scripttask.h index 61913f281..7f55910d3 100644 --- a/base/scripttask.h +++ b/base/scripttask.h @@ -23,20 +23,20 @@ namespace icinga { -class I2_BASE_API ScriptTask : public AsyncTask +class I2_BASE_API ScriptTask : public AsyncTask { public: typedef shared_ptr Ptr; typedef weak_ptr WeakPtr; - ScriptTask(const ScriptFunction::Ptr& function, const vector& arguments); + ScriptTask(const ScriptFunction::Ptr& function, const vector& arguments); protected: virtual void Run(void); private: ScriptFunction::Ptr m_Function; - vector m_Arguments; + vector m_Arguments; }; } diff --git a/base/socket.cpp b/base/socket.cpp index 44b0ccbf3..c1046ab84 100644 --- a/base/socket.cpp +++ b/base/socket.cpp @@ -185,9 +185,9 @@ void Socket::HandleWritable(void) /** * 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 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); @@ -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); @@ -244,16 +244,16 @@ string Socket::GetPeerAddress(void) * @param message The error message. * @param errorCode The error code. */ -SocketException::SocketException(const string& message, int errorCode) +SocketException::SocketException(const String& message, int errorCode) { #ifdef _WIN32 - string details = Win32Exception::FormatErrorCode(errorCode); + String details = Win32Exception::FormatErrorCode(errorCode); #else /* _WIN32 */ - string details = PosixException::FormatErrorCode(errorCode); + String details = PosixException::FormatErrorCode(errorCode); #endif /* _WIN32 */ - string msg = message + ": " + details; - SetMessage(msg.c_str()); + String msg = message + ": " + details; + SetMessage(msg.CStr()); } void Socket::ReadThreadProc(void) diff --git a/base/socket.h b/base/socket.h index f2e6adf01..13c3af0bf 100644 --- a/base/socket.h +++ b/base/socket.h @@ -41,8 +41,8 @@ public: void Close(void); - string GetClientAddress(void); - string GetPeerAddress(void); + String GetClientAddress(void); + String GetPeerAddress(void); mutex& GetMutex(void) const; @@ -87,7 +87,7 @@ private: 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 { public: - SocketException(const string& message, int errorCode); + SocketException(const String& message, int errorCode); }; } diff --git a/base/streamlogger.cpp b/base/streamlogger.cpp index a25b6359e..fe249b30d 100644 --- a/base/streamlogger.cpp +++ b/base/streamlogger.cpp @@ -28,12 +28,12 @@ StreamLogger::~StreamLogger(void) delete m_Stream; } -void StreamLogger::OpenFile(const string& filename) +void StreamLogger::OpenFile(const String& filename) { ofstream *stream = new ofstream(); try { - stream->open(filename.c_str(), ofstream::out | ofstream::trunc); + stream->open(filename.CStr(), ofstream::out | ofstream::trunc); if (!stream->good()) throw_exception(runtime_error("Could not open logfile '" + filename + "'")); diff --git a/base/streamlogger.h b/base/streamlogger.h index 94c4502eb..1d7c99cfb 100644 --- a/base/streamlogger.h +++ b/base/streamlogger.h @@ -17,7 +17,7 @@ public: StreamLogger(std::ostream *stream); ~StreamLogger(void); - void OpenFile(const string& filename); + void OpenFile(const String& filename); protected: virtual void ProcessLogEntry(const LogEntry& entry); diff --git a/base/sysloglogger.cpp b/base/sysloglogger.cpp index ccadfc14f..94455cd56 100644 --- a/base/sysloglogger.cpp +++ b/base/sysloglogger.cpp @@ -30,6 +30,6 @@ void SyslogLogger::ProcessLogEntry(const LogEntry& entry) assert(!"Invalid severity specified."); } - syslog(severity | LOG_USER, "%s", entry.Message.c_str()); + syslog(severity | LOG_USER, "%s", entry.Message.CStr()); } #endif /* _WIN32 */ diff --git a/base/tcpclient.cpp b/base/tcpclient.cpp index 44e5d6d8c..4ea083829 100644 --- a/base/tcpclient.cpp +++ b/base/tcpclient.cpp @@ -47,7 +47,7 @@ TcpClientRole TcpClient::GetRole(void) const * @param node The node. * @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; @@ -59,7 +59,7 @@ void TcpClient::Connect(const string& node, const string& service) hints.ai_socktype = SOCK_STREAM; 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) throw_exception(SocketException("getaddrinfo() failed", GetLastSocketError())); diff --git a/base/tcpclient.h b/base/tcpclient.h index 68a994670..3498f5d7c 100644 --- a/base/tcpclient.h +++ b/base/tcpclient.h @@ -51,7 +51,7 @@ public: TcpClientRole GetRole(void) const; - void Connect(const string& node, const string& service); + void Connect(const String& node, const String& service); boost::signal OnConnected; boost::signal OnDataAvailable; diff --git a/base/tcpsocket.cpp b/base/tcpsocket.cpp index ecdddef2c..0ceedfa18 100644 --- a/base/tcpsocket.cpp +++ b/base/tcpsocket.cpp @@ -44,9 +44,9 @@ void TcpSocket::MakeSocket(int family) * @param service The service. * @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 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 *result; @@ -67,8 +67,8 @@ void TcpSocket::Bind(string node, string service, int family) hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = AI_PASSIVE; - if (getaddrinfo(node.empty() ? NULL : node.c_str(), - service.c_str(), &hints, &result) < 0) + if (getaddrinfo(node.IsEmpty() ? NULL : node.CStr(), + service.CStr(), &hints, &result) < 0) throw_exception(SocketException("getaddrinfo() failed", GetLastSocketError())); int fd = INVALID_SOCKET; diff --git a/base/tcpsocket.h b/base/tcpsocket.h index fc40a9e0f..e1027e108 100644 --- a/base/tcpsocket.h +++ b/base/tcpsocket.h @@ -34,8 +34,8 @@ public: typedef shared_ptr Ptr; typedef weak_ptr WeakPtr; - void Bind(string service, int family); - void Bind(string node, string service, int family); + void Bind(String service, int family); + void Bind(String node, String service, int family); private: void MakeSocket(int family); diff --git a/base/utility.cpp b/base/utility.cpp index f4a300e40..dc0e7b2e7 100644 --- a/base/utility.cpp +++ b/base/utility.cpp @@ -30,16 +30,16 @@ bool I2_EXPORT Utility::m_SSLInitialized = false; * @param ti A type_info 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 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) { - klass = string(realname); + klass = String(realname); free(realname); } #endif /* HAVE_GCC_ABI_DEMANGLE */ @@ -107,7 +107,7 @@ void Utility::InitializeOpenSSL(void) * @param cakey CA certificate chain file. * @returns An SSL context. */ -shared_ptr Utility::MakeSSLContext(string pubkey, string privkey, string cakey) +shared_ptr Utility::MakeSSLContext(String pubkey, String privkey, String cakey) { InitializeOpenSSL(); @@ -115,18 +115,18 @@ shared_ptr Utility::MakeSSLContext(string pubkey, string privkey, strin 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())); - 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())); - 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())); 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) throw_exception(OpenSSLException("SSL_load_client_CA_file() failed", ERR_get_error())); @@ -141,7 +141,7 @@ shared_ptr Utility::MakeSSLContext(string pubkey, string privkey, strin * @param certificate The X509 certificate. * @returns The common name. */ -string Utility::GetCertificateCN(const shared_ptr& certificate) +String Utility::GetCertificateCN(const shared_ptr& certificate) { char buffer[256]; @@ -159,7 +159,7 @@ string Utility::GetCertificateCN(const shared_ptr& certificate) * @param pemfile The filename. * @returns An X509 certificate. */ -shared_ptr Utility::GetX509Certificate(string pemfile) +shared_ptr Utility::GetX509Certificate(String pemfile) { X509 *cert; BIO *fpcert = BIO_new(BIO_s_file()); @@ -167,7 +167,7 @@ shared_ptr Utility::GetX509Certificate(string pemfile) if (fpcert == NULL) 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())); cert = PEM_read_bio_X509_AUX(fpcert, NULL, NULL, NULL); @@ -183,12 +183,12 @@ shared_ptr Utility::GetX509Certificate(string pemfile) * Performs wildcard pattern matching. * * @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. */ -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. * @returns The directory. */ -string Utility::DirName(const string& path) +String Utility::DirName(const String& path) { - char *dir = strdup(path.c_str()); - string result; + char *dir = strdup(path.CStr()); + String result; if (dir == NULL) throw_exception(bad_alloc()); @@ -227,10 +227,10 @@ string Utility::DirName(const string& path) * @param path The full path. * @returns The filename. */ -string Utility::BaseName(const string& path) +String Utility::BaseName(const String& path) { - char *dir = strdup(path.c_str()); - string result; + char *dir = strdup(path.CStr()); + String result; if (dir == NULL) throw_exception(bad_alloc()); diff --git a/base/utility.h b/base/utility.h index 754e03507..11687691b 100644 --- a/base/utility.h +++ b/base/utility.h @@ -31,18 +31,18 @@ namespace icinga class I2_BASE_API Utility { public: - static string GetTypeName(const type_info& ti); + static String GetTypeName(const type_info& ti); static void Daemonize(void); - static shared_ptr MakeSSLContext(string pubkey, string privkey, string cakey); - static string GetCertificateCN(const shared_ptr& certificate); - static shared_ptr GetX509Certificate(string pemfile); + static shared_ptr MakeSSLContext(String pubkey, String privkey, String cakey); + static String GetCertificateCN(const shared_ptr& certificate); + static shared_ptr 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 BaseName(const string& path); + static String DirName(const String& path); + static String BaseName(const String& path); static void NullDeleter(void *obj); diff --git a/base/variant.cpp b/base/value.cpp similarity index 82% rename from base/variant.cpp rename to base/value.cpp index f00d2fb04..9229e7ab0 100644 --- a/base/variant.cpp +++ b/base/value.cpp @@ -27,27 +27,27 @@ using namespace icinga; * * @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)); } -bool Variant::IsScalar(void) const +bool Value::IsScalar(void) const { return !IsEmpty() && !IsObject(); } -bool Variant::IsObject(void) const +bool Value::IsObject(void) const { return !IsEmpty() && (m_Value.type() == typeid(Object::Ptr)); } -Variant Variant::FromJson(cJSON *json) +Value Value::FromJson(cJSON *json) { if (json->type == cJSON_Number) return json->valuedouble; else if (json->type == cJSON_String) - return json->valuestring; + return String(json->valuestring); else if (json->type == cJSON_True) return 1; else if (json->type == cJSON_False) @@ -55,39 +55,39 @@ Variant Variant::FromJson(cJSON *json) else if (json->type == cJSON_Object) return Dictionary::FromJson(json); else if (json->type == cJSON_NULL) - return Variant(); + return Value(); else throw_exception(invalid_argument("Unsupported JSON type.")); } -string Variant::Serialize(void) const +String Value::Serialize(void) const { cJSON *json = ToJson(); char *jsonString; - if (!Application::GetInstance()->IsDebugging()) + if (Application::GetInstance()->IsDebugging()) jsonString = cJSON_Print(json); else jsonString = cJSON_PrintUnformatted(json); cJSON_Delete(json); - string result = jsonString; + String result = jsonString; free(jsonString); return result; } -cJSON *Variant::ToJson(void) const +cJSON *Value::ToJson(void) const { if (m_Value.type() == typeid(long)) { return cJSON_CreateNumber(boost::get(m_Value)); } else if (m_Value.type() == typeid(double)) { return cJSON_CreateNumber(boost::get(m_Value)); - } else if (m_Value.type() == typeid(string)) { - return cJSON_CreateString(boost::get(m_Value).c_str()); + } else if (m_Value.type() == typeid(String)) { + return cJSON_CreateString(boost::get(m_Value).CStr()); } else if (m_Value.type() == typeid(Object::Ptr)) { if (IsObjectType()) { 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) - 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); return value; diff --git a/base/variant.h b/base/value.h similarity index 68% rename from base/variant.h rename to base/value.h index a5c091295..8cd2a6d24 100644 --- a/base/variant.h +++ b/base/value.h @@ -17,8 +17,8 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * ******************************************************************************/ -#ifndef VARIANT_H -#define VARIANT_H +#ifndef VALUE_H +#define VALUE_H struct cJSON; @@ -30,40 +30,40 @@ namespace icinga * * @ingroup base */ -class I2_BASE_API Variant +class I2_BASE_API Value { public: - inline Variant(void) + inline Value(void) : m_Value() { } - inline Variant(int value) - : m_Value(static_cast(value)) - { } - - inline Variant(long value) + inline Value(int value) : m_Value(value) { } - inline Variant(double value) + inline Value(long value) + : m_Value(double(value)) + { } + + inline Value(double value) : m_Value(value) { } - inline Variant(bool value) - : m_Value(static_cast(value)) - { } - - inline Variant(const string& value) + inline Value(const String& value) : m_Value(value) { } - inline Variant(const char *value) - : m_Value(string(value)) + inline Value(const char *value) + : m_Value(String(value)) { } template - inline Variant(const shared_ptr& value) + inline Value(const shared_ptr& value) + : m_Value() { + if (!value) + return; + Object::Ptr object = dynamic_pointer_cast(value); if (!object) @@ -72,20 +72,6 @@ public: 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(m_Value); - } else { - return boost::lexical_cast(m_Value); - } - } else { - return boost::get(m_Value); - } - } - operator double(void) const { if (m_Value.type() != typeid(double)) { @@ -95,20 +81,17 @@ public: } } - operator bool(void) const + operator String(void) const { - return (static_cast(*this) != 0); - } + if (IsEmpty()) + return String(); - operator string(void) const - { - if (m_Value.type() != typeid(string)) { - string result = boost::lexical_cast(m_Value); + if (m_Value.type() != typeid(String)) { + String result = boost::lexical_cast(m_Value); m_Value = result; - return result; - } else { - return boost::get(m_Value); } + + return boost::get(m_Value); } template @@ -138,16 +121,16 @@ public: return (dynamic_pointer_cast(boost::get(m_Value))); } - static Variant FromJson(cJSON *json); + static Value FromJson(cJSON *json); cJSON *ToJson(void) const; - string Serialize(void) const; - static Variant Deserialize(const string& jsonString); + String Serialize(void) const; + static Value Deserialize(const String& jsonString); private: - mutable boost::variant m_Value; + mutable boost::variant m_Value; }; } -#endif /* VARIANT_H */ +#endif /* VALUE_H */ diff --git a/cib/Makefile.am b/cib/Makefile.am index 3ae198c82..e2d5610fe 100644 --- a/cib/Makefile.am +++ b/cib/Makefile.am @@ -4,7 +4,6 @@ pkglib_LTLIBRARIES = \ libcib.la libcib_la_SOURCES = \ - checkresult.cpp \ checkresult.h \ checkresultmessage.cpp \ checkresultmessage.h \ diff --git a/cib/checkresult.cpp b/cib/checkresult.cpp deleted file mode 100644 index 6d5772d9d..000000000 --- a/cib/checkresult.cpp +++ /dev/null @@ -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(state)); -} - -ServiceState CheckResult::GetState(void) const -{ - long value = StateUnknown; - Get("state", &value); - return static_cast(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; -} diff --git a/cib/checkresult.h b/cib/checkresult.h index b3e30c99a..3c0698b95 100644 --- a/cib/checkresult.h +++ b/cib/checkresult.h @@ -23,36 +23,20 @@ namespace icinga { -class I2_CIB_API CheckResult : public MessagePart +/*struct CheckResult { -public: - CheckResult(void); - CheckResult(const MessagePart& message); + static const char *ScheduleStart = "schedule_start"; + static const char *ScheduleEnd = "schedule_end"; + 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); - double GetScheduleStart(void) const; - - 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; -}; +private: + CheckResult(); +};*/ } diff --git a/cib/checkresultmessage.cpp b/cib/checkresultmessage.cpp index d48b9dc6d..35078c30d 100644 --- a/cib/checkresultmessage.cpp +++ b/cib/checkresultmessage.cpp @@ -21,27 +21,13 @@ using namespace icinga; -bool CheckResultMessage::GetService(string *service) const +bool CheckResultMessage::GetService(String *service) const { return Get("service", service); } -void CheckResultMessage::SetService(const string& service) +void CheckResultMessage::SetService(const String& 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()); -} diff --git a/cib/checkresultmessage.h b/cib/checkresultmessage.h index fe4a45eb7..5e37bf05b 100644 --- a/cib/checkresultmessage.h +++ b/cib/checkresultmessage.h @@ -29,11 +29,8 @@ public: CheckResultMessage(void) : MessagePart() { } CheckResultMessage(const MessagePart& message) : MessagePart(message) { } - bool GetService(string *service) const; - void SetService(const string& service); - - bool GetCheckResult(CheckResult *cr) const; - void SetCheckResult(CheckResult cr); + bool GetService(String *service) const; + void SetService(const String& service); }; } diff --git a/cib/cib.vcxproj b/cib/cib.vcxproj index da727b7bc..f8a209ee3 100644 --- a/cib/cib.vcxproj +++ b/cib/cib.vcxproj @@ -82,7 +82,6 @@ - @@ -95,7 +94,6 @@ - diff --git a/cib/cib.vcxproj.filters b/cib/cib.vcxproj.filters index c22572037..2a3cfd9b5 100644 --- a/cib/cib.vcxproj.filters +++ b/cib/cib.vcxproj.filters @@ -11,9 +11,6 @@ - - Headerdateien - Headerdateien @@ -46,9 +43,6 @@ - - Quelldateien - Quelldateien diff --git a/cib/host.cpp b/cib/host.cpp index c2b4c592d..eb4c14447 100644 --- a/cib/host.cpp +++ b/cib/host.cpp @@ -23,22 +23,28 @@ using namespace icinga; REGISTER_CLASS(Host); -string Host::GetAlias(void) const +Host::Host(const Dictionary::Ptr& properties) + : DynamicObject(properties) { - string value; - - if (GetProperty("alias", &value)) - return value; - - return GetName(); + RegisterAttribute("alias", Attribute_Config); + RegisterAttribute("hostgroups", Attribute_Config); } -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)); } -Host::Ptr Host::GetByName(const string& name) +Host::Ptr Host::GetByName(const String& 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 value; - GetProperty("hostgroups", &value); + GetAttribute("hostgroups", &value); return value; } -set Host::GetParents(void) +set Host::GetParents(void) { - set parents; + set parents; Dictionary::Ptr dependencies; - - if (GetProperty("dependencies", &dependencies)) { + GetAttribute("dependencies", &dependencies); + if (dependencies) { dependencies = Service::ResolveDependencies(GetSelf(), dependencies); - Variant dependency; + Value dependency; BOOST_FOREACH(tie(tuples::ignore, dependency), dependencies) { Service::Ptr service = Service::GetByName(dependency); - string parent = service->GetHost()->GetName(); + String parent = service->GetHost()->GetName(); /* ignore ourselves */ if (parent == GetName()) @@ -84,17 +90,18 @@ set Host::GetParents(void) Dictionary::Ptr Host::GetMacros(void) const { Dictionary::Ptr value; - GetProperty("macros", &value); + GetAttribute("macros", &value); return value; } bool Host::IsReachable(void) { Dictionary::Ptr dependencies; - if (GetProperty("dependencies", &dependencies)) { + GetAttribute("dependencies", &dependencies); + if (dependencies) { dependencies = Service::ResolveDependencies(GetSelf(), dependencies); - Variant dependency; + Value dependency; BOOST_FOREACH(tie(tuples::ignore, dependency), dependencies) { Service::Ptr service = Service::GetByName(dependency); @@ -111,10 +118,11 @@ bool Host::IsReachable(void) bool Host::IsUp(void) { Dictionary::Ptr hostchecks; - if (GetProperty("hostchecks", &hostchecks)) { + GetAttribute("hostchecks", &hostchecks); + if (hostchecks) { hostchecks = Service::ResolveDependencies(GetSelf(), hostchecks); - Variant hostcheck; + Value hostcheck; BOOST_FOREACH(tie(tuples::ignore, hostcheck), hostchecks) { Service::Ptr service = Service::GetByName(hostcheck); diff --git a/cib/host.h b/cib/host.h index ae327fbdc..e9b1a9d22 100644 --- a/cib/host.h +++ b/cib/host.h @@ -29,16 +29,14 @@ public: typedef shared_ptr Ptr; typedef weak_ptr WeakPtr; - Host(const Dictionary::Ptr& properties) - : DynamicObject(properties) - { } + Host(const Dictionary::Ptr& properties); - static bool Exists(const string& name); - static Host::Ptr GetByName(const string& name); + static bool Exists(const String& name); + static Host::Ptr GetByName(const String& name); - string GetAlias(void) const; + String GetAlias(void) const; Dictionary::Ptr GetGroups(void) const; - set GetParents(void); + set GetParents(void); Dictionary::Ptr GetMacros(void) const; bool IsReachable(void); diff --git a/cib/hostgroup.cpp b/cib/hostgroup.cpp index 58ddaf3d2..7ce53877b 100644 --- a/cib/hostgroup.cpp +++ b/cib/hostgroup.cpp @@ -23,36 +23,37 @@ using namespace icinga; 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 GetName(); + else + return GetName(); } -string HostGroup::GetNotesUrl(void) const +String HostGroup::GetNotesUrl(void) const { - string value; - GetProperty("notes_url", &value); + String value; + GetAttribute("notes_url", &value); return value; } -string HostGroup::GetActionUrl(void) const +String HostGroup::GetActionUrl(void) const { - string value; - GetProperty("action_url", &value); + String value; + GetAttribute("action_url", &value); return value; } -bool HostGroup::Exists(const string& name) +bool HostGroup::Exists(const String& 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); diff --git a/cib/hostgroup.h b/cib/hostgroup.h index f283e0da9..c40ab0c14 100644 --- a/cib/hostgroup.h +++ b/cib/hostgroup.h @@ -33,12 +33,12 @@ public: : DynamicObject(properties) { } - static bool Exists(const string& name); - static HostGroup::Ptr GetByName(const string& name); + static bool Exists(const String& name); + static HostGroup::Ptr GetByName(const String& name); - string GetAlias(void) const; - string GetNotesUrl(void) const; - string GetActionUrl(void) const; + String GetAlias(void) const; + String GetNotesUrl(void) const; + String GetActionUrl(void) const; }; } diff --git a/cib/macroprocessor.cpp b/cib/macroprocessor.cpp index b2ff0eac7..607cbb3e4 100644 --- a/cib/macroprocessor.cpp +++ b/cib/macroprocessor.cpp @@ -21,36 +21,37 @@ using namespace icinga; -string MacroProcessor::ResolveMacros(const string& str, const vector& macroDicts) +String MacroProcessor::ResolveMacros(const String& str, const vector& macroDicts) { - string::size_type offset, pos_first, pos_second; + size_t offset, pos_first, pos_second; offset = 0; - string result = str; - while ((pos_first = result.find_first_of('$', offset)) != string::npos) { - pos_second = result.find_first_of('$', pos_first + 1); + String result = str; + while ((pos_first = result.FindFirstOf("$", offset)) != String::NPos) { + pos_second = result.FindFirstOf("$", pos_first + 1); - if (pos_second == string::npos) - throw_exception(runtime_error("Closing $ not found in macro format string.")); + if (pos_second == String::NPos) + throw_exception(runtime_error("Closing $ not found in macro format String.")); - string name = result.substr(pos_first + 1, pos_second - pos_first - 1); - string value; + String name = result.SubStr(pos_first + 1, pos_second - pos_first - 1); + String value; bool resolved = false; BOOST_FOREACH(const Dictionary::Ptr& macroDict, macroDicts) { - if (macroDict && macroDict->Get(name, &value)) { - resolved = true; - break; - } + if (!macroDict || !macroDict->Contains(name)) + continue; + + 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) 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; diff --git a/cib/macroprocessor.h b/cib/macroprocessor.h index 224485bb7..f36c6fd80 100644 --- a/cib/macroprocessor.h +++ b/cib/macroprocessor.h @@ -26,7 +26,7 @@ namespace icinga class I2_CIB_API MacroProcessor { public: - static string ResolveMacros(const string& str, const vector& macroDicts); + static String ResolveMacros(const String& str, const vector& macroDicts); }; } diff --git a/cib/nagioschecktask.cpp b/cib/nagioschecktask.cpp index e7568ac18..e95f3dcc9 100644 --- a/cib/nagioschecktask.cpp +++ b/cib/nagioschecktask.cpp @@ -25,30 +25,31 @@ NagiosCheckTask::NagiosCheckTask(const ScriptTask::Ptr& task, const Process::Ptr : m_Task(task), m_Process(process) { } -void NagiosCheckTask::ScriptFunc(const ScriptTask::Ptr& task, const vector& arguments) +void NagiosCheckTask::ScriptFunc(const ScriptTask::Ptr& task, const vector& arguments) { if (arguments.size() < 1) throw_exception(invalid_argument("Missing argument: Service must be specified.")); - Variant vservice = arguments[0]; + Value vservice = arguments[0]; if (!vservice.IsObjectType()) throw_exception(invalid_argument("Argument must be a config object.")); Service::Ptr service = static_cast(vservice); - string checkCommand = service->GetCheckCommand(); + String checkCommand = service->GetCheckCommand(); vector macroDicts; macroDicts.push_back(service->GetMacros()); macroDicts.push_back(service->GetHost()->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(command); NagiosCheckTask ct(task, process); - ct.m_Result.SetScheduleStart(Utility::GetTime()); + ct.m_Result = boost::make_shared(); + ct.m_Result->Set("schedule_start", Utility::GetTime()); process->Start(boost::bind(&NagiosCheckTask::ProcessFinishedHandler, ct)); } @@ -64,11 +65,11 @@ void NagiosCheckTask::ProcessFinishedHandler(NagiosCheckTask ct) return; } - ct.m_Result.SetExecutionStart(pr.ExecutionStart); - ct.m_Result.SetExecutionEnd(pr.ExecutionEnd); + ct.m_Result->Set("execution_start", pr.ExecutionStart); + ct.m_Result->Set("execution_end", pr.ExecutionEnd); - string output = pr.Output; - boost::algorithm::trim(output); + String output = pr.Output; + output.Trim(); ProcessCheckOutput(ct.m_Result, output); ServiceState state; @@ -88,41 +89,40 @@ void NagiosCheckTask::ProcessFinishedHandler(NagiosCheckTask ct) 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 perfdata; + String text; + String perfdata; - vector lines; - boost::algorithm::split(lines, output, is_any_of("\r\n")); + vector lines = output.Split(is_any_of("\r\n")); - BOOST_FOREACH (const string& line, lines) { - string::size_type delim = line.find('|'); + BOOST_FOREACH (const String& line, lines) { + size_t delim = line.FindFirstOf("|"); - if (!text.empty()) - text.append("\n"); + if (!text.IsEmpty()) + text += "\n"; - if (delim != string::npos) { - text.append(line, 0, delim); + if (delim != String::NPos) { + text += line.SubStr(0, delim); - if (!perfdata.empty()) - perfdata.append(" "); + if (!perfdata.IsEmpty()) + perfdata += " "; - perfdata.append(line, delim + 1, line.size()); + perfdata += line.SubStr(delim + 1, line.GetLength()); } else { - text.append(line); + text += line; } } - result.SetOutput(text); - result.SetPerformanceDataRaw(perfdata); + result->Set("output", text); + result->Set("performance_data_raw", perfdata); } void NagiosCheckTask::Register(void) diff --git a/cib/nagioschecktask.h b/cib/nagioschecktask.h index c303c4fc3..94094a5d7 100644 --- a/cib/nagioschecktask.h +++ b/cib/nagioschecktask.h @@ -29,16 +29,16 @@ public: static void Register(void); private: - static void ScriptFunc(const ScriptTask::Ptr& task, const vector& arguments); + static void ScriptFunc(const ScriptTask::Ptr& task, const vector& arguments); 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); ScriptTask::Ptr m_Task; Process::Ptr m_Process; - CheckResult m_Result; + Dictionary::Ptr m_Result; }; } diff --git a/cib/nullchecktask.cpp b/cib/nullchecktask.cpp index 3f0c0ea9a..a0f4c170d 100644 --- a/cib/nullchecktask.cpp +++ b/cib/nullchecktask.cpp @@ -21,21 +21,21 @@ using namespace icinga; -void NullCheckTask::ScriptFunc(const ScriptTask::Ptr& task, const vector& arguments) +void NullCheckTask::ScriptFunc(const ScriptTask::Ptr& task, const vector& arguments) { if (arguments.size() < 1) throw_exception(invalid_argument("Missing argument: Service must be specified.")); double now = Utility::GetTime(); - CheckResult cr; - cr.SetScheduleStart(now); - cr.SetScheduleEnd(now); - cr.SetExecutionStart(now); - cr.SetExecutionEnd(now); - cr.SetState(StateUnknown); + Dictionary::Ptr cr = boost::make_shared(); + cr->Set("schedule_start", now); + cr->Set("schedule_end", now); + cr->Set("execution_start", now); + cr->Set("execution_end", now); + cr->Set("state", StateUnknown); - task->FinishResult(cr.GetDictionary()); + task->FinishResult(cr); } void NullCheckTask::Register(void) diff --git a/cib/nullchecktask.h b/cib/nullchecktask.h index 522ebfce7..255c6e9d7 100644 --- a/cib/nullchecktask.h +++ b/cib/nullchecktask.h @@ -29,7 +29,7 @@ public: static void Register(void); private: - static void ScriptFunc(const ScriptTask::Ptr& task, const vector& arguments); + static void ScriptFunc(const ScriptTask::Ptr& task, const vector& arguments); }; } diff --git a/cib/service.cpp b/cib/service.cpp index 6d410aeb9..959ac1c7f 100644 --- a/cib/service.cpp +++ b/cib/service.cpp @@ -25,22 +25,47 @@ REGISTER_CLASS(Service); boost::signal 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 GetName(); } -bool Service::Exists(const string& name) +bool Service::Exists(const String& 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); @@ -52,8 +77,8 @@ Service::Ptr Service::GetByName(const string& name) Host::Ptr Service::GetHost(void) const { - string hostname; - if (!GetProperty("host_name", &hostname)) + String hostname; + if (!GetAttribute("host_name", &hostname)) throw_exception(runtime_error("Service object is missing the 'host_name' property.")); return Host::GetByName(hostname); @@ -62,28 +87,28 @@ Host::Ptr Service::GetHost(void) const Dictionary::Ptr Service::GetMacros(void) const { Dictionary::Ptr macros; - GetProperty("macros", ¯os); + GetAttribute("macros", ¯os); return macros; } -string Service::GetCheckCommand(void) const +String Service::GetCheckCommand(void) const { - string value; - GetProperty("check_command", &value); + String value; + GetAttribute("check_command", &value); return value; } long Service::GetMaxCheckAttempts(void) const { long value = 3; - GetProperty("max_check_attempts", &value); + GetAttribute("max_check_attempts", &value); return value; } long Service::GetCheckInterval(void) const { long value = 300; - GetProperty("check_interval", &value); + GetAttribute("check_interval", &value); if (value < 15) value = 15; @@ -94,7 +119,7 @@ long Service::GetCheckInterval(void) const long Service::GetRetryInterval(void) const { long value; - if (!GetProperty("retry_interval", &value)) + if (!GetAttribute("retry_interval", &value)) value = GetCheckInterval() / 5; return value; @@ -103,7 +128,7 @@ long Service::GetRetryInterval(void) const Dictionary::Ptr Service::GetDependencies(void) const { Dictionary::Ptr value; - GetProperty("dependencies", &value); + GetAttribute("dependencies", &value); return value; } @@ -115,7 +140,7 @@ void Service::GetDependenciesRecursive(const Dictionary::Ptr& result) const { if (!dependencies) return; - Variant dependency; + Value dependency; BOOST_FOREACH(tie(tuples::ignore, dependency), dependencies) { if (result->Contains(dependency)) continue; @@ -130,14 +155,14 @@ void Service::GetDependenciesRecursive(const Dictionary::Ptr& result) const { Dictionary::Ptr Service::GetGroups(void) const { Dictionary::Ptr value; - GetProperty("servicegroups", &value); + GetAttribute("servicegroups", &value); return value; } Dictionary::Ptr Service::GetCheckers(void) const { Dictionary::Ptr value; - GetProperty("checkers", &value); + GetAttribute("checkers", &value); return value; } @@ -146,7 +171,7 @@ bool Service::IsReachable(void) const Dictionary::Ptr dependencies = boost::make_shared(); GetDependenciesRecursive(dependencies); - Variant dependency; + Value dependency; BOOST_FOREACH(tie(tuples::ignore, dependency), dependencies) { Service::Ptr service = Service::GetByName(dependency); @@ -155,7 +180,7 @@ bool Service::IsReachable(void) const continue; /* ignore pending services */ - if (!service->HasLastCheckResult()) + if (!service->GetLastCheckResult()) continue; /* ignore soft states */ @@ -175,13 +200,13 @@ bool Service::IsReachable(void) const void Service::SetSchedulingOffset(long offset) { - SetTag("scheduling_offset", offset); + SetAttribute("scheduling_offset", offset); } long Service::GetSchedulingOffset(void) { long value; - if (!GetTag("scheduling_offset", &value)) { + if (!GetAttribute("scheduling_offset", &value)) { value = rand(); SetSchedulingOffset(value); } @@ -190,15 +215,17 @@ long Service::GetSchedulingOffset(void) void Service::SetNextCheck(double nextCheck) { - SetTag("next_check", nextCheck); + SetAttribute("next_check", nextCheck); } double Service::GetNextCheck(void) { double value; - if (!GetTag("next_check", &value)) { + if (!GetAttribute("next_check", &value)) { UpdateNextCheck(); - return GetNextCheck(); + + if (!GetAttribute("next_check", &value)) + throw_exception(runtime_error("Failed to schedule next check.")); } return value; } @@ -217,107 +244,100 @@ void Service::UpdateNextCheck(void) 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; - GetTag("checker", &value); + String value; + GetAttribute("checker", &value); return value; } void Service::SetCurrentCheckAttempt(long attempt) { - SetTag("check_attempt", attempt); + SetAttribute("check_attempt", attempt); } long Service::GetCurrentCheckAttempt(void) const { long value = 1; - GetTag("check_attempt", &value); + GetAttribute("check_attempt", &value); return value; } void Service::SetState(ServiceState state) { - SetTag("state", static_cast(state)); + SetAttribute("state", static_cast(state)); } ServiceState Service::GetState(void) const { long value = StateUnknown; - GetTag("state", &value); + GetAttribute("state", &value); return static_cast(value); } void Service::SetStateType(ServiceStateType type) { - SetTag("state_type", static_cast(type)); + SetAttribute("state_type", static_cast(type)); } ServiceStateType Service::GetStateType(void) const { long value = StateTypeHard; - GetTag("state_type", &value); + GetAttribute("state_type", &value); return static_cast(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; - return GetTag("last_result", &value) && 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); + GetAttribute("last_result", &value); + return value; } void Service::SetLastStateChange(double ts) { - SetTag("last_state_change", static_cast(ts)); + SetAttribute("last_state_change", static_cast(ts)); } double Service::GetLastStateChange(void) const { long value; - if (!GetTag("last_state_change", &value)) + if (!GetAttribute("last_state_change", &value)) value = IcingaApplication::GetInstance()->GetStartTime(); return value; } void Service::SetLastHardStateChange(double ts) { - SetTag("last_hard_state_change", ts); + SetAttribute("last_hard_state_change", ts); } double Service::GetLastHardStateChange(void) const { double value; - if (!GetTag("last_hard_state_change", &value)) + if (!GetAttribute("last_hard_state_change", &value)) value = IcingaApplication::GetInstance()->GetStartTime(); return value; } -void Service::ApplyCheckResult(const CheckResult& cr) +void Service::ApplyCheckResult(const Dictionary::Ptr& cr) { ServiceState old_state = GetState(); ServiceStateType old_stateType = GetStateType(); long attempt = GetCurrentCheckAttempt(); - if (cr.GetState() == StateOK) { + if (cr->Get("state") == StateOK) { if (GetState() == StateOK) SetStateType(StateTypeHard); @@ -333,7 +353,9 @@ void Service::ApplyCheckResult(const CheckResult& cr) } SetCurrentCheckAttempt(attempt); - SetState(cr.GetState()); + + int state = cr->Get("state"); + SetState(static_cast(state)); SetLastCheckResult(cr); @@ -345,14 +367,12 @@ void Service::ApplyCheckResult(const CheckResult& cr) if (old_stateType != GetStateType()) SetLastHardStateChange(now); } - - UpdateNextCheck(); } -ServiceState Service::StateFromString(const string& state) +ServiceState Service::StateFromString(const String& state) { /* TODO: make this thread-safe */ - static map stateLookup; + static map stateLookup; if (stateLookup.empty()) { stateLookup["ok"] = StateOK; @@ -362,7 +382,7 @@ ServiceState Service::StateFromString(const string& state) stateLookup["unknown"] = StateUnknown; } - map::iterator it; + map::iterator it; it = stateLookup.find(state); if (it == stateLookup.end()) @@ -371,7 +391,7 @@ ServiceState Service::StateFromString(const string& state) return it->second; } -string Service::StateToString(ServiceState state) +String Service::StateToString(ServiceState state) { switch (state) { 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") return StateTypeSoft; @@ -396,7 +416,7 @@ ServiceStateType Service::StateTypeFromString(const string& type) return StateTypeHard; } -string Service::StateTypeToString(ServiceStateType type) +String Service::StateTypeToString(ServiceStateType type) { if (type == StateTypeSoft) return "soft"; @@ -404,14 +424,14 @@ string Service::StateTypeToString(ServiceStateType type) return "hard"; } -bool Service::IsAllowedChecker(const string& checker) const +bool Service::IsAllowedChecker(const String& checker) const { Dictionary::Ptr checkers = GetCheckers(); if (!checkers) return true; - Variant pattern; + Value pattern; BOOST_FOREACH(tie(tuples::ignore, pattern), checkers) { if (Utility::Match(pattern, checker)) 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 services; - host->GetProperty("services", &services); + host->GetAttribute("services", &services); Dictionary::Ptr result = boost::make_shared(); - Variant dependency; + Value dependency; BOOST_FOREACH(tie(tuples::ignore, dependency), dependencies) { - string name; + String name; if (services && services->Contains(dependency)) - name = host->GetName() + "-" + static_cast(dependency); + name = host->GetName() + "-" + static_cast(dependency); else - name = static_cast(dependency); + name = static_cast(dependency); result->Set(name, name); } diff --git a/cib/service.h b/cib/service.h index dcfa7fae2..6283ed97a 100644 --- a/cib/service.h +++ b/cib/service.h @@ -38,7 +38,6 @@ enum ServiceStateType StateTypeHard }; -class CheckResult; class CheckResultMessage; class ServiceStatusMessage; @@ -48,17 +47,15 @@ public: typedef shared_ptr Ptr; typedef weak_ptr WeakPtr; - Service(const Dictionary::Ptr& properties) - : DynamicObject(properties) - { } + Service(const Dictionary::Ptr& properties); - static bool Exists(const string& name); - static Service::Ptr GetByName(const string& name); + static bool Exists(const String& name); + static Service::Ptr GetByName(const String& name); - string GetAlias(void) const; + String GetAlias(void) const; Host::Ptr GetHost(void) const; Dictionary::Ptr GetMacros(void) const; - string GetCheckCommand(void) const; + String GetCheckCommand(void) const; long GetMaxCheckAttempts(void) const; long GetCheckInterval(void) const; long GetRetryInterval(void) const; @@ -76,10 +73,10 @@ public: double GetNextCheck(void); void UpdateNextCheck(void); - void SetChecker(const string& checker); - string GetChecker(void) const; + void SetChecker(const String& checker); + String GetChecker(void) const; - bool IsAllowedChecker(const string& checker) const; + bool IsAllowedChecker(const String& checker) const; void SetCurrentCheckAttempt(long attempt); long GetCurrentCheckAttempt(void) const; @@ -90,9 +87,8 @@ public: void SetStateType(ServiceStateType type); ServiceStateType GetStateType(void) const; - bool HasLastCheckResult(void) const; - void SetLastCheckResult(const CheckResult& result); - CheckResult GetLastCheckResult(void) const; + void SetLastCheckResult(const Dictionary::Ptr& result); + Dictionary::Ptr GetLastCheckResult(void) const; void SetLastStateChange(double ts); double GetLastStateChange(void) const; @@ -100,13 +96,13 @@ public: void SetLastHardStateChange(double ts); double GetLastHardStateChange(void) const; - void ApplyCheckResult(const CheckResult& cr); + void ApplyCheckResult(const Dictionary::Ptr& cr); - static ServiceState StateFromString(const string& state); - static string StateToString(ServiceState state); + static ServiceState StateFromString(const String& state); + static String StateToString(ServiceState state); - static ServiceStateType StateTypeFromString(const string& state); - static string StateTypeToString(ServiceStateType state); + static ServiceStateType StateTypeFromString(const String& state); + static String StateTypeToString(ServiceStateType state); static Dictionary::Ptr ResolveDependencies(const Host::Ptr& host, const Dictionary::Ptr& dependencies); diff --git a/cib/servicegroup.cpp b/cib/servicegroup.cpp index daca48aab..79b4e07ea 100644 --- a/cib/servicegroup.cpp +++ b/cib/servicegroup.cpp @@ -23,36 +23,37 @@ using namespace icinga; 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 GetName(); + else + return GetName(); } -string ServiceGroup::GetNotesUrl(void) const +String ServiceGroup::GetNotesUrl(void) const { - string value; - GetProperty("notes_url", &value); + String value; + GetAttribute("notes_url", &value); return value; } -string ServiceGroup::GetActionUrl(void) const +String ServiceGroup::GetActionUrl(void) const { - string value; - GetProperty("action_url", &value); + String value; + GetAttribute("action_url", &value); return value; } -bool ServiceGroup::Exists(const string& name) +bool ServiceGroup::Exists(const String& 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); diff --git a/cib/servicegroup.h b/cib/servicegroup.h index d43b5a671..7fdd98f57 100644 --- a/cib/servicegroup.h +++ b/cib/servicegroup.h @@ -33,12 +33,12 @@ public: : DynamicObject(properties) { } - static bool Exists(const string& name); - static ServiceGroup::Ptr GetByName(const string& name); + static bool Exists(const String& name); + static ServiceGroup::Ptr GetByName(const String& name); - string GetAlias(void) const; - string GetNotesUrl(void) const; - string GetActionUrl(void) const; + String GetAlias(void) const; + String GetNotesUrl(void) const; + String GetActionUrl(void) const; }; } diff --git a/components/checker/checkercomponent.cpp b/components/checker/checkercomponent.cpp index bf0944bbc..7bd888ff8 100644 --- a/components/checker/checkercomponent.cpp +++ b/components/checker/checkercomponent.cpp @@ -72,13 +72,13 @@ void CheckerComponent::CheckTimerHandler(void) m_PendingServices.insert(service); - vector arguments; + vector arguments; arguments.push_back(service); ScriptTask::Ptr task; task = service->InvokeMethod("check", arguments, boost::bind(&CheckerComponent::CheckCompletedHandler, this, service, _1)); assert(task); /* TODO: gracefully handle missing methods */ - service->SetTag("current_task", task); + service->SetAttribute("current_task", task); tasks++; } @@ -92,20 +92,22 @@ void CheckerComponent::CheckTimerHandler(void) void CheckerComponent::CheckCompletedHandler(const Service::Ptr& service, const ScriptTask::Ptr& task) { - service->RemoveTag("current_task"); + service->ClearAttribute("current_task"); try { - Variant vresult = task->GetResult(); + Value vresult = task->GetResult(); if (vresult.IsObjectType()) { - CheckResult result = CheckResult(static_cast(vresult)); + Dictionary::Ptr result = vresult; + + service->ApplyCheckResult(result); RequestMessage rm; - rm.SetMethod("checker::CheckResult"); + rm.SetMethod("checker::ServiceStateChange"); + /* TODO: add _old_ state to message */ CheckResultMessage params; params.SetService(service->GetName()); - params.SetCheckResult(result); rm.SetParams(params); @@ -118,11 +120,13 @@ void CheckerComponent::CheckCompletedHandler(const Service::Ptr& service, const Logger::Write(LogWarning, "checker", msgbuf.str()); } - /* figure out when the next check is for this service; the local - * cibsync component should've already done this as part of processing - * the CheckResult message, but lets do it again to be sure */ + /* figure out when the next check is for this service; the call to + * ApplyCheckResult() should've already done this but lets do it again + * just in case there was no check result. */ service->UpdateNextCheck(); + assert(service->GetNextCheck() > Utility::GetTime()); + /* 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 * service to the services list because it's already there. */ @@ -151,7 +155,7 @@ void CheckerComponent::AssignServiceRequestHandler(const Endpoint::Ptr& sender, if (!request.GetParams(¶ms)) return; - string service; + String service; if (!params.Get("service", &service)) return; diff --git a/components/cibsync/cibsynccomponent.cpp b/components/cibsync/cibsynccomponent.cpp index 7516e1879..41547ad92 100644 --- a/components/cibsync/cibsynccomponent.cpp +++ b/components/cibsync/cibsynccomponent.cpp @@ -34,17 +34,18 @@ void CIBSyncComponent::Start(void) m_Endpoint->RegisterTopicHandler("config::FetchObjects", boost::bind(&CIBSyncComponent::FetchObjectsHandler, this, _2)); - DynamicObject::OnCommitted.connect(boost::bind(&CIBSyncComponent::LocalObjectCommittedHandler, this, _1)); - DynamicObject::OnRemoved.connect(boost::bind(&CIBSyncComponent::LocalObjectRemovedHandler, this, _1)); + DynamicObject::OnRegistered.connect(boost::bind(&CIBSyncComponent::LocalObjectRegisteredHandler, 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"); EndpointManager::GetInstance()->OnNewEndpoint.connect(boost::bind(&CIBSyncComponent::NewEndpointHandler, this, _2)); m_Endpoint->RegisterPublication("config::FetchObjects"); - m_Endpoint->RegisterTopicHandler("config::ObjectCommitted", - boost::bind(&CIBSyncComponent::RemoteObjectCommittedHandler, this, _2, _3)); + m_Endpoint->RegisterTopicHandler("config::ObjectUpdate", + boost::bind(&CIBSyncComponent::RemoteObjectUpdateHandler, this, _2, _3)); m_Endpoint->RegisterTopicHandler("config::ObjectRemoved", boost::bind(&CIBSyncComponent::RemoteObjectRemovedHandler, this, _3)); @@ -72,18 +73,18 @@ void CIBSyncComponent::CheckResultRequestHandler(const Endpoint::Ptr& sender, co if (!request.GetParams(¶ms)) return; - string svcname; + String svcname; if (!params.GetService(&svcname)) return; Service::Ptr service = Service::GetByName(svcname); - CheckResult cr; - if (!params.GetCheckResult(&cr)) - return; + //CheckResult cr; + //if (!params.GetCheckResult(&cr)) + // return; - Service::OnCheckResultReceived(service, params); - service->ApplyCheckResult(cr); + //Service::OnCheckResultReceived(service, params); + //service->ApplyCheckResult(cr); time_t now = Utility::GetTime(); CIB::UpdateTaskStatistics(now, 1); @@ -106,7 +107,7 @@ void CIBSyncComponent::SessionEstablishedHandler(const Endpoint::Ptr& endpoint) 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; msg.SetMethod(method); @@ -118,7 +119,7 @@ RequestMessage CIBSyncComponent::MakeObjectMessage(const DynamicObject::Ptr& obj params.Set("type", object->GetType()); if (includeProperties) - params.Set("properties", object->GetProperties()); + params.Set("update", object->BuildUpdate(sinceTx, Attribute_Replicated | Attribute_Config)); return msg; } @@ -138,14 +139,14 @@ void CIBSyncComponent::FetchObjectsHandler(const Endpoint::Ptr& sender) if (!ShouldReplicateObject(object)) continue; - RequestMessage request = MakeObjectMessage(object, "config::ObjectCommitted", true); + RequestMessage request = MakeObjectMessage(object, "config::ObjectUpdate", 0, true); 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 */ if (m_SyncingConfig) @@ -155,10 +156,10 @@ void CIBSyncComponent::LocalObjectCommittedHandler(const DynamicObject::Ptr& obj return; 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 */ if (m_SyncingConfig) @@ -168,66 +169,65 @@ void CIBSyncComponent::LocalObjectRemovedHandler(const DynamicObject::Ptr& objec return; 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& 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; if (!request.GetParams(¶ms)) return; - string name; + String name; if (!params.Get("name", &name)) return; - string type; + String type; if (!params.Get("type", &type)) return; - MessagePart properties; - if (!params.Get("properties", &properties)) + Dictionary::Ptr update; + if (!params.Get("update", &update)) return; DynamicObject::Ptr object = DynamicObject::GetObject(type, name); if (!object) { - object = boost::make_shared(properties.GetDictionary()); + object = DynamicObject::Create(type, update); if (object->GetSource() == EndpointManager::GetInstance()->GetIdentity()) { /* the peer sent us an object that was originally created by us - - * however if was deleted locally so we have to tell the peer to destroy + * however it was deleted locally so we have to tell the peer to destroy * its copy of the object. */ EndpointManager::GetInstance()->SendMulticastMessage(m_Endpoint, - MakeObjectMessage(object, "config::ObjectRemoved", false)); + MakeObjectMessage(object, "config::ObjectRemoved", 0, false)); return; } } else { - DynamicObject::Ptr remoteObject = boost::make_shared(properties.GetDictionary()); + if (object->IsLocal()) + throw_exception(invalid_argument("Replicated remote object is marked as local.")); - if (object->GetCommitTimestamp() >= remoteObject->GetCommitTimestamp()) - return; + if (object->GetSource().IsEmpty()) + object->SetSource(sender->GetIdentity()); - object->SetProperties(properties.GetDictionary()); - } - - 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; + object->ApplyUpdate(update, true); } } @@ -237,11 +237,11 @@ void CIBSyncComponent::RemoteObjectRemovedHandler(const RequestMessage& request) if (!request.GetParams(¶ms)) return; - string name; + String name; if (!params.Get("name", &name)) return; - string type; + String type; if (!params.Get("type", &type)) return; diff --git a/components/cibsync/cibsynccomponent.h b/components/cibsync/cibsynccomponent.h index 3bc46945b..f912e4de3 100644 --- a/components/cibsync/cibsynccomponent.h +++ b/components/cibsync/cibsynccomponent.h @@ -41,15 +41,16 @@ private: void NewEndpointHandler(const Endpoint::Ptr& endpoint); void SessionEstablishedHandler(const Endpoint::Ptr& endpoint); - void LocalObjectCommittedHandler(const DynamicObject::Ptr& object); - void LocalObjectRemovedHandler(const DynamicObject::Ptr& object); + void LocalObjectRegisteredHandler(const DynamicObject::Ptr& object); + void LocalObjectUnregisteredHandler(const DynamicObject::Ptr& object); + void TransactionClosingHandler(const set& modifiedObjects); 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); 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); }; diff --git a/components/compat/compatcomponent.cpp b/components/compat/compatcomponent.cpp index ae288f535..3c7be2b1e 100644 --- a/components/compat/compatcomponent.cpp +++ b/components/compat/compatcomponent.cpp @@ -86,7 +86,7 @@ void CompatComponent::DumpHostObject(ofstream& fp, const Host::Ptr& host) << "\t" << "active_checks_enabled" << "\t" << 1 << "\n" << "\t" << "passive_checks_enabled" << "\t" << 1 << "\n"; - set parents = host->GetParents(); + set parents = host->GetParents(); if (!parents.empty()) { 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) { - string output; - string perfdata; + String output; + String perfdata; double schedule_start = -1, schedule_end = -1; double execution_start = -1, execution_end = -1; - if (service->HasLastCheckResult()) { - CheckResult cr = service->GetLastCheckResult(); - output = cr.GetOutput(); - schedule_start = cr.GetScheduleStart(); - schedule_end = cr.GetScheduleEnd(); - execution_start = cr.GetExecutionStart(); - execution_end = cr.GetExecutionEnd(); - perfdata = cr.GetPerformanceDataRaw(); + + Dictionary::Ptr cr = service->GetLastCheckResult(); + if (cr) { + output = cr->Get("output"); + schedule_start = cr->Get("schedule_start"); + schedule_end = cr->Get("schedule_end"); + execution_start = cr->Get("execution_start"); + execution_end = cr->Get("execution_end"); + perfdata = cr->Get("performance_data_raw"); } double execution_time = (execution_end - execution_start); @@ -122,9 +123,9 @@ void CompatComponent::DumpServiceStatus(ofstream& fp, const Service::Ptr& servic if (!service->IsReachable()) { 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; else output = text + " (" + output + ")"; @@ -138,7 +139,7 @@ void CompatComponent::DumpServiceStatus(ofstream& fp, const Service::Ptr& servic << "\t" << "service_description=" << service->GetAlias() << "\n" << "\t" << "check_interval=" << service->GetCheckInterval() / 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" << "check_execution_time=" << execution_time << "\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" << "\n"; - map > hostgroups; + map > hostgroups; DynamicObject::Ptr object; BOOST_FOREACH(tie(tuples::ignore, object), DynamicObject::GetObjects("Host")) { @@ -230,7 +231,7 @@ void CompatComponent::StatusTimerHandler(void) dict = host->GetGroups(); if (dict) { - Variant hostgroup; + Value hostgroup; BOOST_FOREACH(tie(tuples::ignore, hostgroup), dict) { hostgroups[hostgroup].push_back(host->GetName()); } @@ -240,10 +241,10 @@ void CompatComponent::StatusTimerHandler(void) DumpHostObject(objectfp, host); } - pair > hgt; + pair > hgt; BOOST_FOREACH(hgt, hostgroups) { - const string& name = hgt.first; - const vector& hosts = hgt.second; + const String& name = hgt.first; + const vector& hosts = hgt.second; objectfp << "define hostgroup {" << "\n" << "\t" << "hostgroup_name" << "\t" << name << "\n"; @@ -263,7 +264,7 @@ void CompatComponent::StatusTimerHandler(void) << "}" << "\n"; } - map > servicegroups; + map > servicegroups; BOOST_FOREACH(tie(tuples::ignore, object), DynamicObject::GetObjects("Service")) { Service::Ptr service = static_pointer_cast(object); @@ -273,7 +274,7 @@ void CompatComponent::StatusTimerHandler(void) dict = service->GetGroups(); if (dict) { - Variant servicegroup; + Value servicegroup; BOOST_FOREACH(tie(tuples::ignore, servicegroup), dict) { servicegroups[servicegroup].push_back(service); } @@ -283,9 +284,9 @@ void CompatComponent::StatusTimerHandler(void) DumpServiceObject(objectfp, service); } - pair > sgt; + pair > sgt; BOOST_FOREACH(sgt, servicegroups) { - const string& name = sgt.first; + const String& name = sgt.first; const vector& services = sgt.second; objectfp << "define servicegroup {" << "\n" @@ -300,7 +301,7 @@ void CompatComponent::StatusTimerHandler(void) objectfp << "\t" << "members" << "\t"; - vector sglist; + vector sglist; vector::iterator vt; BOOST_FOREACH(const Service::Ptr& service, services) { diff --git a/components/convenience/conveniencecomponent.cpp b/components/convenience/conveniencecomponent.cpp index 7d700fafb..5f9c6391f 100644 --- a/components/convenience/conveniencecomponent.cpp +++ b/components/convenience/conveniencecomponent.cpp @@ -78,21 +78,21 @@ void ConvenienceComponent::HostCommittedHandler(const ConfigItem::Ptr& item) return; Dictionary::Ptr oldServices; - host->GetTag("convenience-services", &oldServices); + host->GetAttribute("convenience_services", &oldServices); Dictionary::Ptr newServices; newServices = boost::make_shared(); Dictionary::Ptr serviceDescs; - host->GetProperty("services", &serviceDescs); + host->GetAttribute("services", &serviceDescs); if (serviceDescs) { - string svcname; - Variant svcdesc; + String svcname; + Value svcdesc; BOOST_FOREACH(tie(svcname, svcdesc), serviceDescs) { stringstream namebuf; namebuf << item->GetName() << "-" << svcname; - string name = namebuf.str(); + String name = namebuf.str(); ConfigItemBuilder::Ptr builder = boost::make_shared(item->GetDebugInfo()); builder->SetType("service"); @@ -107,7 +107,7 @@ void ConvenienceComponent::HostCommittedHandler(const ConfigItem::Ptr& item) } else if (svcdesc.IsObjectType()) { Dictionary::Ptr service = svcdesc; - string parent; + String parent; if (!service->Get("service", &parent)) 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) @@ -150,7 +150,7 @@ void ConvenienceComponent::HostRemovedHandler(const ConfigItem::Ptr& item) return; Dictionary::Ptr services; - host->GetTag("convenience-services", &services); + host->GetAttribute("convenience_services", &services); if (!services) return; diff --git a/components/delegation/delegationcomponent.cpp b/components/delegation/delegationcomponent.cpp index 161412bab..f7bc18a56 100644 --- a/components/delegation/delegationcomponent.cpp +++ b/components/delegation/delegationcomponent.cpp @@ -24,8 +24,8 @@ using namespace icinga; void DelegationComponent::Start(void) { - DynamicObject::OnCommitted.connect(boost::bind(&DelegationComponent::ServiceCommittedHandler, this, _1)); - DynamicObject::OnRemoved.connect(boost::bind(&DelegationComponent::ServiceRemovedHandler, this, _1)); + DynamicObject::OnRegistered.connect(boost::bind(&DelegationComponent::ServiceCommittedHandler, this, _1)); + DynamicObject::OnUnregistered.connect(boost::bind(&DelegationComponent::ServiceRemovedHandler, this, _1)); m_DelegationTimer = boost::make_shared(); m_DelegationTimer->SetInterval(30); @@ -57,9 +57,9 @@ void DelegationComponent::ServiceCommittedHandler(const DynamicObject::Ptr& obje if (!service) 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 */ service->SetChecker(""); @@ -78,9 +78,9 @@ void DelegationComponent::ServiceRemovedHandler(const DynamicObject::Ptr& object if (!service) 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 */ Endpoint::Ptr endpoint = EndpointManager::GetInstance()->GetEndpointByIdentity(checker); @@ -195,8 +195,8 @@ void DelegationComponent::DelegationTimerHandler(void) services.push_back(service); - string checker = service->GetChecker(); - if (checker.empty()) + String checker = service->GetChecker(); + if (checker.IsEmpty()) continue; Endpoint::Ptr endpoint = EndpointManager::GetInstance()->GetEndpointByIdentity(checker); @@ -213,10 +213,10 @@ void DelegationComponent::DelegationTimerHandler(void) /* re-assign services */ BOOST_FOREACH(const Service::Ptr& service, services) { - string checker = service->GetChecker(); + String checker = service->GetChecker(); Endpoint::Ptr oldEndpoint; - if (!checker.empty()) + if (!checker.IsEmpty()) oldEndpoint = EndpointManager::GetInstance()->GetEndpointByIdentity(checker); vector candidates = GetCheckerCandidates(service); @@ -247,7 +247,7 @@ void DelegationComponent::DelegationTimerHandler(void) continue; /* clear the service's current checker */ - if (!checker.empty()) { + if (!checker.IsEmpty()) { need_clear = true; service->SetChecker(""); @@ -269,7 +269,7 @@ void DelegationComponent::DelegationTimerHandler(void) break; } - assert(candidates.size() == 0 || !service->GetChecker().empty()); + assert(candidates.size() == 0 || !service->GetChecker().IsEmpty()); } Endpoint::Ptr endpoint; @@ -289,7 +289,7 @@ void DelegationComponent::DelegationTimerHandler(void) } BOOST_FOREACH(const Service::Ptr& service, services) { - string checker = service->GetChecker(); + String checker = service->GetChecker(); Endpoint::Ptr endpoint = EndpointManager::GetInstance()->GetEndpointByIdentity(checker); if (!endpoint) diff --git a/components/demo/democomponent.cpp b/components/demo/democomponent.cpp index 8930dc845..5e7158b23 100644 --- a/components/demo/democomponent.cpp +++ b/components/demo/democomponent.cpp @@ -21,16 +21,6 @@ using namespace icinga; -/** - * Returns the name of the component. - * - * @returns The name. - */ -string DemoComponent::GetName(void) const -{ - return "demo"; -} - /** * Starts the component. */ diff --git a/components/demo/democomponent.h b/components/demo/democomponent.h index 76fe90dc9..6eb93af5c 100644 --- a/components/demo/democomponent.h +++ b/components/demo/democomponent.h @@ -29,7 +29,6 @@ namespace icinga class DemoComponent : public IComponent { public: - virtual string GetName(void) const; virtual void Start(void); virtual void Stop(void); diff --git a/components/discovery/discoverycomponent.cpp b/components/discovery/discoverycomponent.cpp index 44326fdd2..8da64c451 100644 --- a/components/discovery/discoverycomponent.cpp +++ b/components/discovery/discoverycomponent.cpp @@ -107,7 +107,7 @@ void DiscoveryComponent::NewEndpointHandler(const Endpoint::Ptr& endpoint) /* accept discovery::Welcome messages from any endpoint */ endpoint->RegisterPublication("discovery::Welcome"); - string identity = endpoint->GetIdentity(); + String identity = endpoint->GetIdentity(); if (identity == EndpointManager::GetInstance()->GetIdentity()) { 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 SendDiscoveryMessage("discovery::RegisterComponent", EndpointManager::GetInstance()->GetIdentity(), endpoint); - map::iterator ic; + map::iterator ic; // we assume the other component _always_ wants // discovery::NewComponent messages from us @@ -156,11 +156,11 @@ void DiscoveryComponent::NewEndpointHandler(const Endpoint::Ptr& endpoint) // register published/subscribed topics for this endpoint ComponentDiscoveryInfo::Ptr info = ic->second; - BOOST_FOREACH(string publication, info->Publications) { + BOOST_FOREACH(String publication, info->Publications) { endpoint->RegisterPublication(publication); } - BOOST_FOREACH(string subscription, info->Subscriptions) { + BOOST_FOREACH(String subscription, info->Subscriptions) { endpoint->RegisterSubscription(subscription); } @@ -192,7 +192,7 @@ void DiscoveryComponent::DiscoveryEndpointHandler(const Endpoint::Ptr& endpoint, * @param info Pointer to the information object. * @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()) { /* Build fake discovery info for ourselves */ @@ -206,7 +206,7 @@ bool DiscoveryComponent::GetComponentDiscoveryInfo(string component, ComponentDi return true; } - map::const_iterator i; + map::const_iterator i; 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 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; request.SetMethod(method); @@ -282,21 +282,21 @@ void DiscoveryComponent::SendDiscoveryMessage(const string& method, const string if (!GetComponentDiscoveryInfo(identity, &info)) return; - if (!info->Node.empty() && !info->Service.empty()) { + if (!info->Node.IsEmpty() && !info->Service.IsEmpty()) { params.SetNode(info->Node); params.SetService(info->Service); } - set::iterator i; + set::iterator i; Dictionary::Ptr subscriptions = boost::make_shared(); - BOOST_FOREACH(string subscription, info->Subscriptions) { + BOOST_FOREACH(String subscription, info->Subscriptions) { subscriptions->Add(subscription); } params.SetSubscriptions(subscriptions); Dictionary::Ptr publications = boost::make_shared(); - BOOST_FOREACH(string publication, info->Publications) { + BOOST_FOREACH(String publication, info->Publications) { publications->Add(publication); } @@ -308,18 +308,19 @@ void DiscoveryComponent::SendDiscoveryMessage(const string& method, const string 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) return false; - DynamicObject::Ptr role; - BOOST_FOREACH(tie(tuples::ignore, role), DynamicObject::GetObjects("Role")) { + Value roleName; + BOOST_FOREACH(tie(tuples::ignore, roleName), roles) { + DynamicObject::Ptr role = DynamicObject::GetObject("Role", roleName); Dictionary::Ptr permissions; - if (!role->GetProperty(messageType, &permissions)) + if (!role->GetAttribute(messageType, &permissions)) continue; - Variant permission; + Value permission; BOOST_FOREACH(tie(tuples::ignore, permission), permissions) { if (Utility::Match(permission, message)) return true; @@ -337,7 +338,7 @@ bool DiscoveryComponent::HasMessagePermission(const Dictionary::Ptr& roles, cons * @param message The discovery message. * @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 */ if (identity == EndpointManager::GetInstance()->GetIdentity()) @@ -347,24 +348,24 @@ void DiscoveryComponent::ProcessDiscoveryMessage(const string& identity, const D info->LastSeen = Utility::GetTime(); - string node; - if (message.GetNode(&node) && !node.empty()) + String node; + if (message.GetNode(&node) && !node.IsEmpty()) info->Node = node; - string service; - if (message.GetService(&service) && !service.empty()) + String service; + if (message.GetService(&service) && !service.IsEmpty()) info->Service = service; DynamicObject::Ptr endpointConfig = DynamicObject::GetObject("endpoint", identity); Dictionary::Ptr roles; if (endpointConfig) - endpointConfig->GetProperty("roles", &roles); + endpointConfig->GetAttribute("roles", &roles); Endpoint::Ptr endpoint = EndpointManager::GetInstance()->GetEndpointByIdentity(identity); Dictionary::Ptr publications; if (message.GetPublications(&publications)) { - Variant publication; + Value publication; BOOST_FOREACH(tie(tuples::ignore, publication), publications) { if (trusted || HasMessagePermission(roles, "publications", publication)) { info->Publications.insert(publication); @@ -376,7 +377,7 @@ void DiscoveryComponent::ProcessDiscoveryMessage(const string& identity, const D Dictionary::Ptr subscriptions; if (message.GetSubscriptions(&subscriptions)) { - Variant subscription; + Value subscription; BOOST_FOREACH(tie(tuples::ignore, subscription), subscriptions) { if (trusted || HasMessagePermission(roles, "subscriptions", subscription)) { info->Subscriptions.insert(subscription); @@ -386,7 +387,7 @@ void DiscoveryComponent::ProcessDiscoveryMessage(const string& identity, const D } } - map::iterator i; + map::iterator i; i = m_Components.find(identity); @@ -412,7 +413,7 @@ void DiscoveryComponent::NewComponentMessageHandler(const RequestMessage& reques DiscoveryMessage message; request.GetParams(&message); - string identity; + String identity; if (!message.GetIdentity(&identity)) return; @@ -448,16 +449,16 @@ void DiscoveryComponent::DiscoveryTimerHandler(void) if (endpointManager->GetEndpointByIdentity(object->GetName())) continue; - string node, service; - if (object->GetProperty("node", &node) && object->GetProperty("service", &service)) { + String node, service; + if (object->GetAttribute("node", &node) && object->GetAttribute("service", &service)) { /* reconnect to this endpoint */ endpointManager->AddConnection(node, service); } } - map::iterator curr, i; + map::iterator curr, i; 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; curr = i; @@ -491,7 +492,7 @@ void DiscoveryComponent::DiscoveryTimerHandler(void) /* TODO: figure out whether we actually want to connect to this component */ /* try and reconnect to this component */ try { - if (!info->Node.empty() && !info->Service.empty()) + if (!info->Node.IsEmpty() && !info->Service.IsEmpty()) endpointManager->AddConnection(info->Node, info->Service); } catch (const exception& ex) { stringstream msgbuf; diff --git a/components/discovery/discoverycomponent.h b/components/discovery/discoverycomponent.h index 539bd6f18..629d78b3e 100644 --- a/components/discovery/discoverycomponent.h +++ b/components/discovery/discoverycomponent.h @@ -32,11 +32,11 @@ public: typedef shared_ptr Ptr; typedef weak_ptr WeakPtr; - string Node; - string Service; + String Node; + String Service; - set Subscriptions; - set Publications; + set Subscriptions; + set Publications; double LastSeen; }; @@ -52,7 +52,7 @@ public: private: VirtualEndpoint::Ptr m_Endpoint; - map m_Components; + map m_Components; Timer::Ptr m_DiscoveryTimer; void NewEndpointHandler(const Endpoint::Ptr& endpoint); @@ -62,10 +62,10 @@ private: void WelcomeMessageHandler(const Endpoint::Ptr& sender, const RequestMessage& request); - void SendDiscoveryMessage(const string& method, const string& identity, const Endpoint::Ptr& recipient); - void ProcessDiscoveryMessage(const string& identity, const DiscoveryMessage& message, bool trusted); + void SendDiscoveryMessage(const String& method, const String& identity, const Endpoint::Ptr& recipient); + 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 DiscoveryEndpointHandler(const Endpoint::Ptr& endpoint, const ComponentDiscoveryInfo::Ptr& info) const; @@ -74,7 +74,7 @@ private: 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; }; diff --git a/components/discovery/discoverymessage.cpp b/components/discovery/discoverymessage.cpp index 354cf01df..6f22c7bd8 100644 --- a/components/discovery/discoverymessage.cpp +++ b/components/discovery/discoverymessage.cpp @@ -29,32 +29,32 @@ DiscoveryMessage::DiscoveryMessage(const MessagePart& message) : MessagePart(message) { } -bool DiscoveryMessage::GetIdentity(string *value) const +bool DiscoveryMessage::GetIdentity(String *value) const { return Get("identity", value); } -void DiscoveryMessage::SetIdentity(const string& value) +void DiscoveryMessage::SetIdentity(const String& value) { Set("identity", value); } -bool DiscoveryMessage::GetNode(string *value) const +bool DiscoveryMessage::GetNode(String *value) const { return Get("node", value); } -void DiscoveryMessage::SetNode(const string& value) +void DiscoveryMessage::SetNode(const String& value) { Set("node", value); } -bool DiscoveryMessage::GetService(string *value) const +bool DiscoveryMessage::GetService(String *value) const { return Get("service", value); } -void DiscoveryMessage::SetService(const string& value) +void DiscoveryMessage::SetService(const String& value) { Set("service", value); } diff --git a/components/discovery/discoverymessage.h b/components/discovery/discoverymessage.h index 9cce48a90..9d6379afe 100644 --- a/components/discovery/discoverymessage.h +++ b/components/discovery/discoverymessage.h @@ -32,14 +32,14 @@ public: DiscoveryMessage(void); DiscoveryMessage(const MessagePart& message); - bool GetIdentity(string *value) const; - void SetIdentity(const string& value); + bool GetIdentity(String *value) const; + void SetIdentity(const String& value); - bool GetNode(string *value) const; - void SetNode(const string& value); + bool GetNode(String *value) const; + void SetNode(const String& value); - bool GetService(string *value) const; - void SetService(const string& value); + bool GetService(String *value) const; + void SetService(const String& value); bool GetSubscriptions(Dictionary::Ptr *value) const; void SetSubscriptions(const Dictionary::Ptr& value); diff --git a/dyn/config_parser.cc b/dyn/config_parser.cc index 8748a0a8c..068902ac7 100644 --- a/dyn/config_parser.cc +++ b/dyn/config_parser.cc @@ -173,7 +173,7 @@ typedef union YYSTYPE char *text; double num; - icinga::Variant *variant; + icinga::Value *variant; icinga::ExpressionOperator op; @@ -1636,7 +1636,7 @@ yyreduce: /* Line 1806 of yacc.c */ #line 166 "config_parser.yy" { - (yyval.variant) = new Variant(m_ExpressionLists.top()); + (yyval.variant) = new Value(m_ExpressionLists.top()); m_ExpressionLists.pop(); } break; @@ -1699,7 +1699,7 @@ yyreduce: /* Line 1806 of yacc.c */ #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)); } break; @@ -1709,7 +1709,7 @@ yyreduce: /* Line 1806 of yacc.c */ #line 227 "config_parser.yy" { - (yyval.variant) = new Variant((yyvsp[(1) - (1)].num)); + (yyval.variant) = new Value((yyvsp[(1) - (1)].num)); } break; @@ -1718,7 +1718,7 @@ yyreduce: /* Line 1806 of yacc.c */ #line 231 "config_parser.yy" { - (yyval.variant) = new Variant(); + (yyval.variant) = new Value(); } break; diff --git a/dyn/config_parser.h b/dyn/config_parser.h index 4c8ee9402..31820abe6 100644 --- a/dyn/config_parser.h +++ b/dyn/config_parser.h @@ -116,7 +116,7 @@ typedef union YYSTYPE char *text; double num; - icinga::Variant *variant; + icinga::Value *variant; icinga::ExpressionOperator op; diff --git a/dyn/config_parser.yy b/dyn/config_parser.yy index ec1d78964..a9a6e716f 100644 --- a/dyn/config_parser.yy +++ b/dyn/config_parser.yy @@ -38,7 +38,7 @@ using namespace icinga; %union { char *text; double num; - icinga::Variant *variant; + icinga::Value *variant; icinga::ExpressionOperator op; } @@ -164,7 +164,7 @@ expressionlist: '{' expressions '}' { - $$ = new Variant(m_ExpressionLists.top()); + $$ = new Value(m_ExpressionLists.top()); m_ExpressionLists.pop(); } ; @@ -220,16 +220,16 @@ operator: T_EQUAL simplevalue: T_STRING { - $$ = new Variant($1); + $$ = new Value($1); free($1); } | T_NUMBER { - $$ = new Variant($1); + $$ = new Value($1); } | T_NULL { - $$ = new Variant(); + $$ = new Value(); } ; diff --git a/dyn/configcompiler.cpp b/dyn/configcompiler.cpp index b3d60ba72..b781b850f 100644 --- a/dyn/configcompiler.cpp +++ b/dyn/configcompiler.cpp @@ -23,7 +23,7 @@ using std::ifstream; 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) { InitializeScanner(); @@ -50,29 +50,29 @@ vector ConfigCompiler::GetResult(void) const return m_Result; } -string ConfigCompiler::GetPath(void) const +String ConfigCompiler::GetPath(void) const { 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 items = m_HandleInclude(path); std::copy(items.begin(), items.end(), back_inserter(m_Result)); } -vector ConfigCompiler::CompileStream(const string& path, istream *stream) +vector ConfigCompiler::CompileStream(const String& path, istream *stream) { ConfigCompiler ctx(path, stream); ctx.Compile(); return ctx.GetResult(); } -vector ConfigCompiler::CompileFile(const string& path) +vector ConfigCompiler::CompileFile(const String& path) { ifstream stream; - stream.open(path.c_str(), ifstream::in); + stream.open(path.CStr(), ifstream::in); if (!stream) throw_exception(invalid_argument("Could not open config file: " + path)); @@ -82,13 +82,13 @@ vector ConfigCompiler::CompileFile(const string& path) return CompileStream(path, &stream); } -vector ConfigCompiler::CompileText(const string& path, const string& text) +vector ConfigCompiler::CompileText(const String& path, const String& text) { stringstream stream(text); return CompileStream(path, &stream); } -vector ConfigCompiler::HandleFileInclude(const string& include) +vector ConfigCompiler::HandleFileInclude(const String& include) { /* TODO: implement wildcard includes */ return CompileFile(include); diff --git a/dyn/configcompiler.h b/dyn/configcompiler.h index f1e167ce5..b2c7e9fa8 100644 --- a/dyn/configcompiler.h +++ b/dyn/configcompiler.h @@ -26,32 +26,32 @@ namespace icinga class I2_DYN_API ConfigCompiler { public: - typedef function (const string& include)> HandleIncludeFunc; + typedef function (const String& include)> HandleIncludeFunc; - ConfigCompiler(const string& path, istream *input = &cin, + ConfigCompiler(const String& path, istream *input = &cin, HandleIncludeFunc includeHandler = &ConfigCompiler::HandleFileInclude); virtual ~ConfigCompiler(void); void Compile(void); - static vector CompileStream(const string& path, istream *stream); - static vector CompileFile(const string& path); - static vector CompileText(const string& path, const string& text); + static vector CompileStream(const String& path, istream *stream); + static vector CompileFile(const String& path); + static vector CompileText(const String& path, const String& text); - static vector HandleFileInclude(const string& include); + static vector HandleFileInclude(const String& include); vector GetResult(void) const; - string GetPath(void) const; + String GetPath(void) const; /* internally used methods */ - void HandleInclude(const string& include); + void HandleInclude(const String& include); void AddObject(const ConfigItem::Ptr& object); size_t ReadInput(char *buffer, size_t max_bytes); void *GetScanner(void) const; private: - string m_Path; + String m_Path; istream *m_Input; HandleIncludeFunc m_HandleInclude; diff --git a/dyn/configitem.cpp b/dyn/configitem.cpp index f445eefa5..17341cfd6 100644 --- a/dyn/configitem.cpp +++ b/dyn/configitem.cpp @@ -25,20 +25,20 @@ ConfigItem::ItemMap ConfigItem::m_Items; boost::signal ConfigItem::OnCommitted; boost::signal ConfigItem::OnRemoved; -ConfigItem::ConfigItem(const string& type, const string& name, - const ExpressionList::Ptr& exprl, const vector& parents, +ConfigItem::ConfigItem(const String& type, const String& name, + const ExpressionList::Ptr& exprl, const vector& parents, const DebugInfo& debuginfo) : m_Type(type), m_Name(name), m_ExpressionList(exprl), m_Parents(parents), m_DebugInfo(debuginfo) { } -string ConfigItem::GetType(void) const +String ConfigItem::GetType(void) const { return m_Type; } -string ConfigItem::GetName(void) const +String ConfigItem::GetName(void) const { return m_Name; } @@ -53,14 +53,14 @@ ExpressionList::Ptr ConfigItem::GetExpressionList(void) const return m_ExpressionList; } -vector ConfigItem::GetParents(void) const +vector ConfigItem::GetParents(void) const { 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); if (!parent) { @@ -82,20 +82,38 @@ DynamicObject::Ptr ConfigItem::Commit(void) Dictionary::Ptr properties = boost::make_shared(); CalculateProperties(properties); + /* Create a fake update in the format that + * DynamicObject::ApplyUpdate expects. */ + Dictionary::Ptr attrs = boost::make_shared(); + + String key; + Value data; + BOOST_FOREACH(tie(key, data), properties) { + Dictionary::Ptr attr = boost::make_shared(); + attr->Set("data", data); + attr->Set("type", Attribute_Config); + attr->Set("tx", DynamicObject::GetCurrentTx()); + attrs->Set(key, attr); + } + + Dictionary::Ptr update = boost::make_shared(); + update->Set("attrs", attrs); + update->Set("configTx", DynamicObject::GetCurrentTx()); + if (!dobj) dobj = DynamicObject::GetObject(GetType(), GetName()); if (!dobj) - dobj = DynamicObject::Create(GetType(), properties); + dobj = DynamicObject::Create(GetType(), update); else - dobj->SetProperties(properties); + dobj->ApplyUpdate(update); m_DynamicObject = dobj; if (dobj->IsAbstract()) dobj->Unregister(); else - dobj->Commit(); + dobj->Register(); /* TODO: Figure out whether there are any child objects which inherit * from this config item and Commit() them as well */ @@ -128,7 +146,7 @@ DynamicObject::Ptr ConfigItem::GetDynamicObject(void) const 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; it = m_Items.find(make_pair(type, name)); diff --git a/dyn/configitem.h b/dyn/configitem.h index 8df8edb77..260232d2f 100644 --- a/dyn/configitem.h +++ b/dyn/configitem.h @@ -28,19 +28,17 @@ public: typedef shared_ptr Ptr; typedef weak_ptr WeakPtr; - ConfigItem(const string& type, const string& name, - const ExpressionList::Ptr& exprl, const vector& parents, + ConfigItem(const String& type, const String& name, + const ExpressionList::Ptr& exprl, const vector& parents, const DebugInfo& debuginfo); - string GetType(void) const; - string GetName(void) const; + String GetType(void) const; + String GetName(void) const; - vector GetParents(void) const; + vector GetParents(void) const; ExpressionList::Ptr GetExpressionList(void) const; - void CalculateProperties(Dictionary::Ptr dictionary) const; - DynamicObject::Ptr Commit(void); void Unregister(void); @@ -48,22 +46,24 @@ public: 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 OnCommitted; static boost::signal OnRemoved; private: - string m_Type; - string m_Name; + void CalculateProperties(const Dictionary::Ptr& dictionary) const; + + String m_Type; + String m_Name; ExpressionList::Ptr m_ExpressionList; - vector m_Parents; + vector m_Parents; DebugInfo m_DebugInfo; DynamicObject::WeakPtr m_DynamicObject; - typedef map, ConfigItem::Ptr> ItemMap; + typedef map, ConfigItem::Ptr> ItemMap; static ItemMap m_Items; }; diff --git a/dyn/configitembuilder.cpp b/dyn/configitembuilder.cpp index fc5c61d23..4894ab48e 100644 --- a/dyn/configitembuilder.cpp +++ b/dyn/configitembuilder.cpp @@ -38,12 +38,12 @@ ConfigItemBuilder::ConfigItemBuilder(const DebugInfo& debugInfo) m_DebugInfo = debugInfo; } -void ConfigItemBuilder::SetType(const string& type) +void ConfigItemBuilder::SetType(const String& type) { m_Type = type; } -void ConfigItemBuilder::SetName(const string& name) +void ConfigItemBuilder::SetName(const String& name) { m_Name = name; } @@ -58,7 +58,7 @@ void ConfigItemBuilder::SetAbstract(bool abstract) m_Abstract = abstract; } -void ConfigItemBuilder::AddParent(const string& parent) +void ConfigItemBuilder::AddParent(const String& parent) { m_Parents.push_back(parent); } @@ -68,7 +68,7 @@ void ConfigItemBuilder::AddExpression(const Expression& 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); AddExpression(expr); @@ -81,8 +81,8 @@ void ConfigItemBuilder::AddExpressionList(const ExpressionList::Ptr& exprl) ConfigItem::Ptr ConfigItemBuilder::Compile(void) { - assert(!m_Type.empty()); - assert(!m_Name.empty()); + assert(!m_Type.IsEmpty()); + assert(!m_Name.IsEmpty()); ExpressionList::Ptr exprl = boost::make_shared(); diff --git a/dyn/configitembuilder.h b/dyn/configitembuilder.h index 5f4190216..0d3ed6630 100644 --- a/dyn/configitembuilder.h +++ b/dyn/configitembuilder.h @@ -32,25 +32,25 @@ public: ConfigItemBuilder(void); ConfigItemBuilder(const DebugInfo& debugInfo); - void SetType(const string& type); - void SetName(const string& name); + void SetType(const String& type); + void SetName(const String& name); void SetLocal(bool local); void SetAbstract(bool abstract); - void AddParent(const string& parent); + void AddParent(const String& parent); 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); ConfigItem::Ptr Compile(void); private: - string m_Type; - string m_Name; + String m_Type; + String m_Name; bool m_Local; bool m_Abstract; - vector m_Parents; + vector m_Parents; ExpressionList::Ptr m_ExpressionList; DebugInfo m_DebugInfo; }; diff --git a/dyn/debuginfo.h b/dyn/debuginfo.h index e58227624..c6999a9bb 100644 --- a/dyn/debuginfo.h +++ b/dyn/debuginfo.h @@ -25,7 +25,7 @@ namespace icinga struct DebugInfo { - string Path; + String Path; union { diff --git a/dyn/expression.cpp b/dyn/expression.cpp index b9f2b5c43..1aa842789 100644 --- a/dyn/expression.cpp +++ b/dyn/expression.cpp @@ -21,14 +21,14 @@ 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) { } void Expression::Execute(const Dictionary::Ptr& dictionary) const { - Variant oldValue, newValue; + Value oldValue, newValue; ExpressionList::Ptr valueExprl; Dictionary::Ptr valueDict; @@ -61,7 +61,7 @@ void Expression::Execute(const Dictionary::Ptr& dictionary) const break; case OperatorPlus: - dictionary->Get(m_Key, &oldValue); + oldValue = dictionary->Get(m_Key); if (oldValue.IsObjectType()) dict = oldValue; @@ -81,8 +81,8 @@ void Expression::Execute(const Dictionary::Ptr& dictionary) const if (valueExprl) { valueExprl->Execute(dict); } else if (valueDict) { - string key; - Variant value; + String key; + Value value; BOOST_FOREACH(tie(key, value), valueDict) { dict->Set(key, value); } diff --git a/dyn/expression.h b/dyn/expression.h index 5ef8b5c32..5cf82e5f4 100644 --- a/dyn/expression.h +++ b/dyn/expression.h @@ -36,14 +36,14 @@ enum ExpressionOperator struct I2_DYN_API Expression { 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; private: - string m_Key; + String m_Key; ExpressionOperator m_Operator; - Variant m_Value; + Value m_Value; DebugInfo m_DebugInfo; }; diff --git a/icinga-app/icinga-standalone.conf b/icinga-app/icinga-standalone.conf index 0ac2ad7f4..897efddfc 100644 --- a/icinga-app/icinga-standalone.conf +++ b/icinga-app/icinga-standalone.conf @@ -1,14 +1,14 @@ local object Application "icinga" { -/* cert = "icinga-c1.pem", + cert = "icinga-c1.pem", ca = "ca.crt", node = "192.168.2.235", - service = 7777*/ + service = 7777 } -/*local object Component "discovery" { +local object Component "discovery" { -}*/ +} 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" } } @@ -33,7 +37,7 @@ local object Endpoint "icinga-c4" { local object Role "all" { publications = { "*" }, subscriptions = { "*" } -}*/ +} object Host "localhost" { diff --git a/icinga.sln b/icinga.sln index cdbcdd5ba..b42f25601 100644 --- a/icinga.sln +++ b/icinga.sln @@ -21,9 +21,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "icinga", "icinga\icinga.vcx EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "icinga-app", "icinga-app\icinga-app.vcxproj", "{BE412865-FEBA-4259-AD41-58950D1F5432}" ProjectSection(ProjectDependencies) = postProject + {2BD1C70C-43DB-4F44-B66B-67CF5C7044AA} = {2BD1C70C-43DB-4F44-B66B-67CF5C7044AA} {EAD41628-BB96-4F99-9070-8A9676801295} = {EAD41628-BB96-4F99-9070-8A9676801295} {2E6C1133-730F-4875-A72C-B455B1DD4C5C} = {2E6C1133-730F-4875-A72C-B455B1DD4C5C} {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} {C1FC77E1-04A4-481B-A78B-2F7AF489C2F8} = {C1FC77E1-04A4-481B-A78B-2F7AF489C2F8} EndProjectSection @@ -158,12 +161,12 @@ Global HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {2E6C1133-730F-4875-A72C-B455B1DD4C5C} = {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} {17C93245-8C20-4316-9573-1AE41D918C10} = {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} {D02A349B-BAF7-41FB-86FF-B05BA05FE578} = {4A1773FD-DDED-4952-8700-C898E890554A} + {2E6C1133-730F-4875-A72C-B455B1DD4C5C} = {4A1773FD-DDED-4952-8700-C898E890554A} EndGlobalSection EndGlobal diff --git a/icinga/endpoint.cpp b/icinga/endpoint.cpp index b37479267..d5466e8ad 100644 --- a/icinga/endpoint.cpp +++ b/icinga/endpoint.cpp @@ -46,7 +46,7 @@ void Endpoint::SetEndpointManager(EndpointManager::WeakPtr manager) * * @param topic The name of the topic. */ -void Endpoint::RegisterSubscription(string topic) +void Endpoint::RegisterSubscription(String topic) { m_Subscriptions.insert(topic); } @@ -56,7 +56,7 @@ void Endpoint::RegisterSubscription(string topic) * * @param topic The name of the topic. */ -void Endpoint::UnregisterSubscription(string topic) +void Endpoint::UnregisterSubscription(String topic) { m_Subscriptions.erase(topic); } @@ -67,7 +67,7 @@ void Endpoint::UnregisterSubscription(string topic) * @param topic The name of the topic. * @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()); } @@ -77,7 +77,7 @@ bool Endpoint::HasSubscription(string topic) const * * @param topic The name of the topic. */ -void Endpoint::RegisterPublication(string topic) +void Endpoint::RegisterPublication(String topic) { m_Publications.insert(topic); } @@ -87,7 +87,7 @@ void Endpoint::RegisterPublication(string topic) * * @param topic The name of the topic. */ -void Endpoint::UnregisterPublication(string topic) +void Endpoint::UnregisterPublication(String topic) { m_Publications.erase(topic); } @@ -98,7 +98,7 @@ void Endpoint::UnregisterPublication(string topic) * @param topic The name of the topic. * @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()); } diff --git a/icinga/endpoint.h b/icinga/endpoint.h index eaa056dce..d853dd61a 100644 --- a/icinga/endpoint.h +++ b/icinga/endpoint.h @@ -36,14 +36,14 @@ public: typedef shared_ptr Ptr; typedef weak_ptr WeakPtr; - typedef set::const_iterator ConstTopicIterator; + typedef set::const_iterator ConstTopicIterator; Endpoint(void) : m_ReceivedWelcome(false), m_SentWelcome(false) { } - virtual string GetIdentity(void) const = 0; - virtual string GetAddress(void) const = 0; + virtual String GetIdentity(void) const = 0; + virtual String GetAddress(void) const = 0; void SetReceivedWelcome(bool value); bool HasReceivedWelcome(void) const; @@ -54,13 +54,13 @@ public: shared_ptr GetEndpointManager(void) const; void SetEndpointManager(weak_ptr manager); - void RegisterSubscription(string topic); - void UnregisterSubscription(string topic); - bool HasSubscription(string topic) const; + void RegisterSubscription(String topic); + void UnregisterSubscription(String topic); + bool HasSubscription(String topic) const; - void RegisterPublication(string topic); - void UnregisterPublication(string topic); - bool HasPublication(string topic) const; + void RegisterPublication(String topic); + void UnregisterPublication(String topic); + bool HasPublication(String topic) const; virtual bool IsLocal(void) const = 0; virtual bool IsConnected(void) const = 0; @@ -82,9 +82,9 @@ public: boost::signal OnSessionEstablished; private: - set m_Subscriptions; /**< The topics this endpoint is + set m_Subscriptions; /**< The topics this endpoint is subscribed to. */ - set m_Publications; /**< The topics this endpoint is + set m_Publications; /**< The topics this endpoint is publishing. */ bool m_ReceivedWelcome; /**< Have we received a welcome message from this endpoint? */ diff --git a/icinga/endpointmanager.cpp b/icinga/endpointmanager.cpp index 12a95c597..bda7176f0 100644 --- a/icinga/endpointmanager.cpp +++ b/icinga/endpointmanager.cpp @@ -39,7 +39,7 @@ EndpointManager::EndpointManager(void) * * @param identity The new identity. */ -void EndpointManager::SetIdentity(const string& identity) +void EndpointManager::SetIdentity(const String& identity) { m_Identity = identity; } @@ -49,7 +49,7 @@ void EndpointManager::SetIdentity(const string& identity) * * @returns The identity. */ -string EndpointManager::GetIdentity(void) const +String EndpointManager::GetIdentity(void) const { return m_Identity; } @@ -79,7 +79,7 @@ shared_ptr EndpointManager::GetSSLContext(void) const * * @param service The port to listen on. */ -void EndpointManager::AddListener(const string& service) +void EndpointManager::AddListener(const String& service) { if (!GetSSLContext()) 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 service The remote port. */ -void EndpointManager::AddConnection(const string& node, const string& service) +void EndpointManager::AddConnection(const String& node, const String& service) { stringstream s; s << "Adding new endpoint: [" << node << "]:" << service; @@ -164,9 +164,9 @@ void EndpointManager::RegisterEndpoint(const Endpoint::Ptr& endpoint) UnregisterEndpoint(endpoint); - string identity = endpoint->GetIdentity(); + String identity = endpoint->GetIdentity(); - if (!identity.empty()) { + if (!identity.IsEmpty()) { m_Endpoints[identity] = endpoint; OnNewEndpoint(GetSelf(), endpoint); } else { @@ -200,8 +200,8 @@ void EndpointManager::UnregisterEndpoint(const Endpoint::Ptr& endpoint) remove(m_PendingEndpoints.begin(), m_PendingEndpoints.end(), endpoint), m_PendingEndpoints.end()); - string identity = endpoint->GetIdentity(); - if (!identity.empty()) + String identity = endpoint->GetIdentity(); + if (!identity.IsEmpty()) m_Endpoints.erase(identity); } @@ -235,7 +235,7 @@ void EndpointManager::SendUnicastMessage(const Endpoint::Ptr& sender, void EndpointManager::SendAnycastMessage(const Endpoint::Ptr& sender, const RequestMessage& message) { - string method; + String method; if (!message.GetMethod(&method)) 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, const RequestMessage& message) { - string id; + String id; if (message.GetID(&id)) throw_exception(invalid_argument("Multicast requests must not have an ID.")); - string method; + String method; if (!message.GetMethod(&method)) 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 callback) { - map::iterator prev, i; + map::iterator prev, i; for (i = m_Endpoints.begin(); i != m_Endpoints.end(); ) { prev = i; i++; @@ -307,9 +307,9 @@ void EndpointManager::ForEachEndpoint(function::const_iterator i; + map::const_iterator i; i = m_Endpoints.find(identity); if (i != m_Endpoints.end()) return i->second; @@ -326,7 +326,7 @@ void EndpointManager::SendAPIMessage(const Endpoint::Ptr& sender, const Endpoint stringstream idstream; idstream << m_NextMessageID; - string id = idstream.str(); + String id = idstream.str(); message.SetID(id); PendingRequest pr; @@ -342,15 +342,15 @@ void EndpointManager::SendAPIMessage(const Endpoint::Ptr& sender, const Endpoint SendUnicastMessage(sender, recipient, message); } -bool EndpointManager::RequestTimeoutLessComparer(const pair& a, - const pair& b) +bool EndpointManager::RequestTimeoutLessComparer(const pair& a, + const pair& b) { return a.second.Timeout < b.second.Timeout; } void EndpointManager::RequestTimerHandler(void) { - map::iterator it; + map::iterator it; for (it = m_Requests.begin(); it != m_Requests.end(); it++) { if (it->second.HasTimedOut()) { 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) { - string id; + String id; if (!message.GetID(&id)) throw_exception(invalid_argument("Response message must have a message ID.")); - map::iterator it; + map::iterator it; it = m_Requests.find(id); if (it == m_Requests.end()) diff --git a/icinga/endpointmanager.h b/icinga/endpointmanager.h index e539072b1..869a01922 100644 --- a/icinga/endpointmanager.h +++ b/icinga/endpointmanager.h @@ -34,20 +34,20 @@ public: typedef shared_ptr Ptr; typedef weak_ptr WeakPtr; - typedef map::iterator Iterator; + typedef map::iterator Iterator; EndpointManager(void); static EndpointManager::Ptr GetInstance(void); - void SetIdentity(const string& identity); - string GetIdentity(void) const; + void SetIdentity(const String& identity); + String GetIdentity(void) const; void SetSSLContext(const shared_ptr& sslContext); shared_ptr GetSSLContext(void) const; - void AddListener(const string& service); - void AddConnection(const string& node, const string& service); + void AddListener(const String& service); + void AddConnection(const String& node, const String& service); void RegisterEndpoint(const Endpoint::Ptr& endpoint); void UnregisterEndpoint(const Endpoint::Ptr& endpoint); @@ -65,17 +65,17 @@ public: Iterator Begin(void); Iterator End(void); - Endpoint::Ptr GetEndpointByIdentity(const string& identity) const; + Endpoint::Ptr GetEndpointByIdentity(const String& identity) const; boost::signal OnNewEndpoint; private: - string m_Identity; + String m_Identity; shared_ptr m_SSLContext; vector m_Servers; vector m_PendingEndpoints; - map m_Endpoints; + map m_Endpoints; /** * Information about a pending API request. @@ -95,13 +95,13 @@ private: }; long m_NextMessageID; - map m_Requests; + map m_Requests; Timer::Ptr m_RequestTimer; void RegisterServer(const JsonRpcServer::Ptr& server); void UnregisterServer(const JsonRpcServer::Ptr& server); - static bool RequestTimeoutLessComparer(const pair& a, const pair& b); + static bool RequestTimeoutLessComparer(const pair& a, const pair& b); void RequestTimerHandler(void); void NewClientHandler(const TcpClient::Ptr& client); diff --git a/icinga/icingaapplication.cpp b/icinga/icingaapplication.cpp index cfd8cd9b6..17ed3ce56 100644 --- a/icinga/icingaapplication.cpp +++ b/icinga/icingaapplication.cpp @@ -28,7 +28,7 @@ using namespace icinga; -const string IcingaApplication::DefaultPidPath = "icinga.pid"; +const String IcingaApplication::DefaultPidPath = "icinga.pid"; IcingaApplication::IcingaApplication(void) : m_PidPath(DefaultPidPath) @@ -40,7 +40,7 @@ IcingaApplication::IcingaApplication(void) * @param args Command-line arguments. * @returns An exit status. */ -int IcingaApplication::Main(const vector& args) +int IcingaApplication::Main(const vector& args) { /* create console logger */ ConfigItemBuilder::Ptr consoleLogConfig = boost::make_shared(); @@ -55,7 +55,7 @@ int IcingaApplication::Main(const vector& args) /* periodically dump the program state */ m_RetentionTimer = boost::make_shared(); - m_RetentionTimer->SetInterval(60); + m_RetentionTimer->SetInterval(10); m_RetentionTimer->OnTimerExpired.connect(boost::bind(&IcingaApplication::DumpProgramState, this)); m_RetentionTimer->Start(); @@ -76,15 +76,15 @@ int IcingaApplication::Main(const vector& args) bool daemonize = false; bool parseOpts = true; - string configFile; + String configFile; /* TODO: clean up this mess; for now it will just have to do */ - vector::const_iterator it; + vector::const_iterator it; for (it = args.begin() + 1 ; it != args.end(); it++) { - string arg = *it; + String arg = *it; /* ignore empty arguments */ - if (arg.empty()) + if (arg.IsEmpty()) continue; if (arg == "--") { @@ -107,10 +107,10 @@ int IcingaApplication::Main(const vector& args) 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.")); - string componentDirectory = Utility::DirName(GetExePath()) + "/../lib/icinga2"; + String componentDirectory = Utility::DirName(GetExePath()) + "/../lib/icinga2"; Component::AddSearchDir(componentDirectory); /* load cibsync config component */ @@ -125,7 +125,7 @@ int IcingaApplication::Main(const vector& args) convenienceComponentConfig->SetType("Component"); convenienceComponentConfig->SetName("convenience"); convenienceComponentConfig->SetLocal(true); - convenienceComponentConfig->Compile()->Commit(); + //convenienceComponentConfig->Compile()->Commit(); /* load config file */ vector configItems = ConfigCompiler::CompileFile(configFile); @@ -144,15 +144,16 @@ int IcingaApplication::Main(const vector& args) if (!icingaConfig->IsLocal()) throw_exception(runtime_error("'icinga' application object must be 'local'.")); - icingaConfig->GetProperty("cert", &m_CertificateFile); - icingaConfig->GetProperty("ca", &m_CAFile); - icingaConfig->GetProperty("node", &m_Node); - icingaConfig->GetProperty("service", &m_Service); - icingaConfig->GetProperty("pidpath", &m_PidPath); - icingaConfig->GetProperty("macros", &m_Macros); + icingaConfig->GetAttribute("cert", &m_CertificateFile); + icingaConfig->GetAttribute("ca", &m_CAFile); + icingaConfig->GetAttribute("node", &m_Node); + icingaConfig->GetAttribute("service", &m_Service); + icingaConfig->GetAttribute("pidpath", &m_PidPath); + icingaConfig->GetAttribute("macros", &m_Macros); - string logpath; - if (icingaConfig->GetProperty("logpath", &logpath)) { + String logpath; + icingaConfig->GetAttribute("logpath", &logpath); + if (!logpath.IsEmpty()) { ConfigItemBuilder::Ptr fileLogConfig = boost::make_shared(); fileLogConfig->SetType("Logger"); fileLogConfig->SetName("main"); @@ -164,10 +165,10 @@ int IcingaApplication::Main(const vector& args) UpdatePidFile(GetPidPath()); - if (!GetCertificateFile().empty() && !GetCAFile().empty()) { + if (!GetCertificateFile().IsEmpty() && !GetCAFile().IsEmpty()) { /* set up SSL context */ shared_ptr cert = Utility::GetX509Certificate(GetCertificateFile()); - string identity = Utility::GetCertificateCN(cert); + String identity = Utility::GetCertificateCN(cert); Logger::Write(LogInformation, "icinga", "My identity: " + identity); EndpointManager::GetInstance()->SetIdentity(identity); @@ -176,8 +177,8 @@ int IcingaApplication::Main(const vector& args) } /* create the primary RPC listener */ - string service = GetService(); - if (!service.empty()) + String service = GetService(); + if (!service.IsEmpty()) EndpointManager::GetInstance()->AddListener(service); if (daemonize) { @@ -206,27 +207,27 @@ IcingaApplication::Ptr IcingaApplication::GetInstance(void) return static_pointer_cast(Application::GetInstance()); } -string IcingaApplication::GetCertificateFile(void) const +String IcingaApplication::GetCertificateFile(void) const { return m_CertificateFile; } -string IcingaApplication::GetCAFile(void) const +String IcingaApplication::GetCAFile(void) const { return m_CAFile; } -string IcingaApplication::GetNode(void) const +String IcingaApplication::GetNode(void) const { return m_Node; } -string IcingaApplication::GetService(void) const +String IcingaApplication::GetService(void) const { return m_Service; } -string IcingaApplication::GetPidPath(void) const +String IcingaApplication::GetPidPath(void) const { return m_PidPath; } diff --git a/icinga/icingaapplication.h b/icinga/icingaapplication.h index acd3b3949..0bc10e4fd 100644 --- a/icinga/icingaapplication.h +++ b/icinga/icingaapplication.h @@ -36,27 +36,27 @@ public: IcingaApplication(void); - int Main(const vector& args); + int Main(const vector& args); static IcingaApplication::Ptr GetInstance(void); - string GetCertificateFile(void) const; - string GetCAFile(void) const; - string GetNode(void) const; - string GetService(void) const; - string GetPidPath(void) const; + String GetCertificateFile(void) const; + String GetCAFile(void) const; + String GetNode(void) const; + String GetService(void) const; + String GetPidPath(void) const; Dictionary::Ptr GetMacros(void) const; time_t GetStartTime(void) const; - static const string DefaultPidPath; + static const String DefaultPidPath; private: - string m_CertificateFile; - string m_CAFile; - string m_Node; - string m_Service; - string m_PidPath; + String m_CertificateFile; + String m_CAFile; + String m_Node; + String m_Service; + String m_PidPath; Dictionary::Ptr m_Macros; time_t m_StartTime; diff --git a/icinga/jsonrpcendpoint.cpp b/icinga/jsonrpcendpoint.cpp index 676843f27..f392ccb30 100644 --- a/icinga/jsonrpcendpoint.cpp +++ b/icinga/jsonrpcendpoint.cpp @@ -21,12 +21,12 @@ using namespace icinga; -string JsonRpcEndpoint::GetIdentity(void) const +String JsonRpcEndpoint::GetIdentity(void) const { return m_Identity; } -string JsonRpcEndpoint::GetAddress(void) const +String JsonRpcEndpoint::GetAddress(void) const { if (!m_Client) return ""; @@ -39,7 +39,7 @@ JsonRpcClient::Ptr JsonRpcEndpoint::GetClient(void) return m_Client; } -void JsonRpcEndpoint::Connect(string node, string service, shared_ptr sslContext) +void JsonRpcEndpoint::Connect(String node, String service, shared_ptr sslContext) { JsonRpcClient::Ptr client = boost::make_shared(RoleOutbound, sslContext); SetClient(client); @@ -92,14 +92,14 @@ void JsonRpcEndpoint::NewMessageHandler(const MessagePart& message) RequestMessage request = message; - string method; + String method; if (!request.GetMethod(&method)) return; if (!HasPublication(method)) return; - string id; + String id; if (request.GetID(&id)) GetEndpointManager()->SendAnycastMessage(sender, request); else @@ -137,9 +137,9 @@ void JsonRpcEndpoint::ClientClosedHandler(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; GetEndpointManager()->RegisterEndpoint(GetSelf()); } diff --git a/icinga/jsonrpcendpoint.h b/icinga/jsonrpcendpoint.h index fab47d6bc..e685aac30 100644 --- a/icinga/jsonrpcendpoint.h +++ b/icinga/jsonrpcendpoint.h @@ -35,14 +35,14 @@ public: typedef shared_ptr Ptr; typedef weak_ptr WeakPtr; - void Connect(string node, string service, + void Connect(String node, String service, shared_ptr sslContext); JsonRpcClient::Ptr GetClient(void); void SetClient(JsonRpcClient::Ptr client); - virtual string GetIdentity(void) const; - virtual string GetAddress(void) const; + virtual String GetIdentity(void) const; + virtual String GetAddress(void) const; virtual bool IsLocal(void) const; virtual bool IsConnected(void) const; @@ -53,13 +53,13 @@ public: virtual void Stop(void); private: - string m_Identity; /**< The identity of this endpoint. */ + String m_Identity; /**< The identity of this endpoint. */ shared_ptr m_SSLContext; - string m_Address; + String m_Address; JsonRpcClient::Ptr m_Client; - void SetAddress(string address); + void SetAddress(String address); void NewMessageHandler(const MessagePart& message); void ClientClosedHandler(void); diff --git a/icinga/virtualendpoint.cpp b/icinga/virtualendpoint.cpp index 8dfe7bf49..c82bf3f24 100644 --- a/icinga/virtualendpoint.cpp +++ b/icinga/virtualendpoint.cpp @@ -21,12 +21,12 @@ using namespace icinga; -string VirtualEndpoint::GetIdentity(void) const +String VirtualEndpoint::GetIdentity(void) const { return "__" + GetAddress(); } -string VirtualEndpoint::GetAddress(void) const +String VirtualEndpoint::GetAddress(void) const { char address[50]; sprintf(address, "virtual:%p", (void *)this); @@ -43,9 +43,9 @@ bool VirtualEndpoint::IsConnected(void) const return true; } -void VirtualEndpoint::RegisterTopicHandler(string topic, function callback) +void VirtualEndpoint::RegisterTopicHandler(String topic, function callback) { - map > >::iterator it; + map > >::iterator it; it = m_TopicHandlers.find(topic); shared_ptr > sig; @@ -62,7 +62,7 @@ void VirtualEndpoint::RegisterTopicHandler(string topic, function callback) +void VirtualEndpoint::UnregisterTopicHandler(String topic, function callback) { // TODO: implement //m_TopicHandlers[method] -= callback; @@ -73,11 +73,11 @@ void VirtualEndpoint::UnregisterTopicHandler(string topic, function > >::iterator it; + map > >::iterator it; it = m_TopicHandlers.find(method); if (it == m_TopicHandlers.end()) diff --git a/icinga/virtualendpoint.h b/icinga/virtualendpoint.h index efa25eb33..f81b6f833 100644 --- a/icinga/virtualendpoint.h +++ b/icinga/virtualendpoint.h @@ -34,11 +34,11 @@ public: typedef shared_ptr Ptr; typedef weak_ptr WeakPtr; - void RegisterTopicHandler(string topic, function callback); - void UnregisterTopicHandler(string topic, function callback); + void RegisterTopicHandler(String topic, function callback); + void UnregisterTopicHandler(String topic, function callback); - virtual string GetIdentity(void) const; - virtual string GetAddress(void) const; + virtual String GetIdentity(void) const; + virtual String GetAddress(void) const; virtual bool IsLocal(void) const; virtual bool IsConnected(void) const; @@ -49,7 +49,7 @@ public: virtual void Stop(void); private: - map< string, shared_ptr > > m_TopicHandlers; + map< String, shared_ptr > > m_TopicHandlers; }; } diff --git a/jsonrpc/jsonrpcclient.cpp b/jsonrpc/jsonrpcclient.cpp index 446de0b44..29cca0888 100644 --- a/jsonrpc/jsonrpcclient.cpp +++ b/jsonrpc/jsonrpcclient.cpp @@ -40,8 +40,8 @@ JsonRpcClient::JsonRpcClient(TcpClientRole role, shared_ptr sslContext) */ void JsonRpcClient::SendMessage(const MessagePart& message) { - Variant value = message.GetDictionary(); - Netstring::WriteStringToIOQueue(this, value.Serialize()); + Value value = message.GetDictionary(); + NetString::WriteStringToIOQueue(this, value.Serialize()); } /** @@ -49,18 +49,18 @@ void JsonRpcClient::SendMessage(const MessagePart& message) */ void JsonRpcClient::DataAvailableHandler(void) { - string jsonString; + String jsonString; - while (Netstring::ReadStringFromIOQueue(this, &jsonString)) { + while (NetString::ReadStringFromIOQueue(this, &jsonString)) { try { - Variant value = Variant::Deserialize(jsonString); + Value value = Value::Deserialize(jsonString); if (!value.IsObjectType()) throw_exception(invalid_argument("JSON-RPC message must be a dictionary.")); OnNewMessage(GetSelf(), MessagePart(value)); } 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())); } } } diff --git a/jsonrpc/messagepart.cpp b/jsonrpc/messagepart.cpp index 1e90322ce..fd42b91b6 100644 --- a/jsonrpc/messagepart.cpp +++ b/jsonrpc/messagepart.cpp @@ -66,12 +66,16 @@ Dictionary::Ptr MessagePart::GetDictionary(void) const * @param[out] The value. * @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; - if (!GetDictionary()->Get(key, &dictionary)) + Value v; + v = GetDictionary()->Get(key); + + if (!v.IsObjectType()) return false; + Dictionary::Ptr dictionary = v; + *value = MessagePart(dictionary); return true; } @@ -82,7 +86,7 @@ bool MessagePart::Get(string key, MessagePart *value) const * @param key The name of the property. * @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()); } @@ -125,7 +129,7 @@ Dictionary::Iterator MessagePart::End(void) * @param key The name of the element. * @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); } diff --git a/jsonrpc/messagepart.h b/jsonrpc/messagepart.h index 8a6cc021c..6caec2a6f 100644 --- a/jsonrpc/messagepart.h +++ b/jsonrpc/messagepart.h @@ -49,9 +49,15 @@ public: * @returns true if the value was retrieved, false otherwise. */ template - 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(v); + return true; } /** @@ -61,13 +67,13 @@ public: * @param value The value. */ template - void Set(string key, const T& value) + void Set(String key, const T& value) { GetDictionary()->Set(key, value); } - bool Get(string key, MessagePart *value) const; - void Set(string key, const MessagePart& value); + bool Get(String key, MessagePart *value) const; + void Set(String key, const MessagePart& value); /** * Adds an item to the message using an automatically generated property name. @@ -82,7 +88,7 @@ public: void Add(const MessagePart& value); - bool Contains(const string& key) const; + bool Contains(const String& key) const; Dictionary::Iterator Begin(void); Dictionary::Iterator End(void); diff --git a/jsonrpc/requestmessage.h b/jsonrpc/requestmessage.h index 6f571c5e0..544524f65 100644 --- a/jsonrpc/requestmessage.h +++ b/jsonrpc/requestmessage.h @@ -51,7 +51,7 @@ public: * @param[out] value The value. * @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); } @@ -61,7 +61,7 @@ public: * * @param value The version. */ - inline void SetVersion(const string& value) + inline void SetVersion(const String& value) { Set("jsonrpc", value); } @@ -72,7 +72,7 @@ public: * @param[out] value The method. * @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); } @@ -82,7 +82,7 @@ public: * * @param value The method. */ - inline void SetMethod(const string& value) + inline void SetMethod(const String& value) { Set("method", value); } @@ -114,7 +114,7 @@ public: * @param[out] value The ID. * @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); } @@ -124,7 +124,7 @@ public: * * @param value The ID. */ - inline void SetID(const string& value) + inline void SetID(const String& value) { Set("id", value); } diff --git a/jsonrpc/responsemessage.h b/jsonrpc/responsemessage.h index 39466409b..7c631fb9c 100644 --- a/jsonrpc/responsemessage.h +++ b/jsonrpc/responsemessage.h @@ -51,7 +51,7 @@ public: * @param[out] value The value. * @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); } @@ -61,7 +61,7 @@ public: * * @param value The version. */ - inline void SetVersion(const string& value) + inline void SetVersion(const String& value) { Set("jsonrpc", value); } @@ -93,7 +93,7 @@ public: * @param[out] value The error message. * @returns true if the value was retrieved, false otherwise. */ - bool GetError(string *value) const + bool GetError(String *value) const { return Get("error", value); } @@ -103,7 +103,7 @@ public: * * @param value The error message. */ - void SetError(const string& value) + void SetError(const String& value) { Set("error", value); } @@ -114,7 +114,7 @@ public: * @param[out] value The ID. * @return true if the value was retrieved, false otherwise. */ - bool GetID(string *value) const + bool GetID(String *value) const { return Get("id", value); } @@ -124,7 +124,7 @@ public: * * @param value The ID. */ - void SetID(const string& value) + void SetID(const String& value) { Set("id", value); } diff --git a/third-party/cJSON/cJSON.c b/third-party/cJSON/cJSON.c index 263f2f9f2..523d4f1e1 100644 --- a/third-party/cJSON/cJSON.c +++ b/third-party/cJSON/cJSON.c @@ -131,8 +131,7 @@ static char *print_number(cJSON *item) if (str) { if (fabs(floor(d)-d)<=DBL_EPSILON) sprintf(str,"%.0f",d); - else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%.16e",d); - else sprintf(str,"%f",d); + else sprintf(str,"%.*e",(int)log10(d) + 6,d); } } return str;