diff --git a/components/Makefile.am b/components/Makefile.am
index b49409e38..092faf4a9 100644
--- a/components/Makefile.am
+++ b/components/Makefile.am
@@ -6,7 +6,6 @@ SUBDIRS = \
compat \
delegation \
demo \
- ido_log \
ido_mysql \
livestatus \
notification \
diff --git a/components/ido_log/.gitignore b/components/ido_log/.gitignore
deleted file mode 100644
index f7032c2ff..000000000
--- a/components/ido_log/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-ido_log-type.cpp
diff --git a/components/ido_log/Makefile.am b/components/ido_log/Makefile.am
deleted file mode 100644
index 6cb07b291..000000000
--- a/components/ido_log/Makefile.am
+++ /dev/null
@@ -1,38 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-pkglib_LTLIBRARIES = \
- libido_log.la
-
-EXTRA_DIST = \
- ido_log-type.conf
-
-.conf.cpp: $(top_builddir)/tools/mkembedconfig/mkembedconfig.c
- $(top_builddir)/tools/mkembedconfig/mkembedconfig $< $@
-
-libido_log_la_SOURCES = \
- ido_log-type.cpp \
- logdbconnection.cpp \
- logdbconnection.h
-
-libido_log_la_CPPFLAGS = \
- $(LTDLINCL) \
- $(BOOST_CPPFLAGS) \
- -I${top_srcdir}/lib \
- -I${top_srcdir}/components
-
-libido_log_la_LDFLAGS = \
- $(BOOST_LDFLAGS) \
- -module \
- -no-undefined \
- @RELEASE_INFO@ \
- @VERSION_INFO@
-
-libido_log_la_LIBADD = \
- $(BOOST_SIGNALS_LIB) \
- $(BOOST_THREAD_LIB) \
- $(BOOST_SYSTEM_LIB) \
- ${top_builddir}/lib/base/libbase.la \
- ${top_builddir}/lib/config/libconfig.la \
- ${top_builddir}/lib/remoting/libremoting.la \
- ${top_builddir}/lib/icinga/libicinga.la \
- ${top_builddir}/lib/ido/libido.la
diff --git a/components/ido_log/ido_log-type.conf b/components/ido_log/ido_log-type.conf
deleted file mode 100644
index a983b7743..000000000
--- a/components/ido_log/ido_log-type.conf
+++ /dev/null
@@ -1,28 +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. *
- ******************************************************************************/
-
-type MysqlDbConnection {
- %attribute string "host",
- %attribute number "port",
-
- %attribute string "user",
- %attribute string "password",
-
- %attribute string "database",
-}
diff --git a/components/ido_log/ido_log.vcxproj b/components/ido_log/ido_log.vcxproj
deleted file mode 100644
index fcf55e5d2..000000000
--- a/components/ido_log/ido_log.vcxproj
+++ /dev/null
@@ -1,193 +0,0 @@
-
-
-
-
- Debug
- Win32
-
-
- Debug
- x64
-
-
- Release
- Win32
-
-
- Release
- x64
-
-
-
- {2E6C1133-730F-4875-A72C-B455B1DD4C5C}
- Win32Proj
- demo
-
-
-
- DynamicLibrary
- true
- MultiByte
-
-
- DynamicLibrary
- true
- MultiByte
-
-
- DynamicLibrary
- false
- true
- MultiByte
-
-
- DynamicLibrary
- false
- true
- MultiByte
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- true
- $(SolutionDir)\lib;$(SolutionDir)\components;$(IncludePath)
- $(SolutionDir)$(Platform)\$(Configuration)\;$(LibraryPath)
- $(SolutionDir)$(Platform)\$(Configuration)\
- $(Platform)\$(Configuration)\
-
-
- true
- $(SolutionDir)\lib;$(SolutionDir)\components;$(IncludePath)
- $(SolutionDir)$(Platform)\$(Configuration)\;$(LibraryPath)
- $(SolutionDir)$(Platform)\$(Configuration)\
- $(Platform)\$(Configuration)\
-
-
- false
- $(SolutionDir)\lib;$(SolutionDir)\components;$(IncludePath)
- $(SolutionDir)$(Platform)\$(Configuration)\;$(LibraryPath)
- $(SolutionDir)$(Platform)\$(Configuration)\
- $(Platform)\$(Configuration)\
-
-
- false
- $(SolutionDir)\lib;$(SolutionDir)\components;$(IncludePath)
- $(SolutionDir)$(Platform)\$(Configuration)\;$(LibraryPath)
- $(SolutionDir)$(Platform)\$(Configuration)\
- $(Platform)\$(Configuration)\
-
-
-
- Disabled
- _DEBUG;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
- Level3
- false
- true
- NotUsing
-
-
- Windows
- true
- base.lib;config.lib;remoting.lib;icinga.lib;%(AdditionalDependencies)
-
-
-
-
- Disabled
- _DEBUG;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;_WINDOWS;%(PreprocessorDefinitions)
- Level3
- false
- true
- NotUsing
-
-
- Windows
- true
- base.lib;config.lib;remoting.lib;icinga.lib;%(AdditionalDependencies)
-
-
-
-
- MaxSpeed
- true
- true
- NDEBUG;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
- Level3
- false
- true
- NotUsing
-
-
- Windows
- true
- true
- true
- base.lib;config.lib;remoting.lib;icinga.lib;%(AdditionalDependencies)
-
-
-
-
- MaxSpeed
- true
- true
- NDEBUG;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
- Level3
- false
- true
- NotUsing
-
-
- Windows
- true
- true
- true
- base.lib;config.lib;remoting.lib;icinga.lib;%(AdditionalDependencies)
-
-
-
-
-
-
-
-
-
-
-
-
- Document
- "$(SolutionDir)$(Platform)\$(Configuration)\mkembedconfig.exe" "%(Identity)" "%(Filename).cpp"
- Preparing config fragment for embedding
- "$(SolutionDir)$(Platform)\$(Configuration)\mkembedconfig.exe" "%(Identity)" "%(Filename).cpp"
- Preparing config fragment for embedding
- "$(SolutionDir)$(Platform)\$(Configuration)\mkembedconfig.exe" "%(Identity)" "%(Filename).cpp"
- Preparing config fragment for embedding
- "$(SolutionDir)$(Platform)\$(Configuration)\mkembedconfig.exe" "%(Identity)" "%(Filename).cpp"
- Preparing config fragment for embedding
- %(Filename).cpp;%(Outputs)
- %(Filename).cpp;%(Outputs)
- %(Filename).cpp;%(Outputs)
- %(Filename).cpp;%(Outputs)
- $(SolutionDir)\tools\mkembedconfig\mkembedconfig.c
- $(SolutionDir)\tools\mkembedconfig\mkembedconfig.c
- $(SolutionDir)\tools\mkembedconfig\mkembedconfig.c
- $(SolutionDir)\tools\mkembedconfig\mkembedconfig.c
-
-
-
-
-
-
\ No newline at end of file
diff --git a/components/ido_log/ido_log.vcxproj.filters b/components/ido_log/ido_log.vcxproj.filters
deleted file mode 100644
index 922435a52..000000000
--- a/components/ido_log/ido_log.vcxproj.filters
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
- Headerdateien
-
-
- Headerdateien
-
-
-
-
- {11a495bf-a705-4766-b3d3-9b5db266a6ef}
-
-
- {1fb6337f-a17f-46ea-9316-2d800a94b53d}
-
-
-
-
- Quelldateien
-
-
- Quelldateien
-
-
-
-
- Quelldateien
-
-
-
\ No newline at end of file
diff --git a/components/ido_log/logdbconnection.cpp b/components/ido_log/logdbconnection.cpp
deleted file mode 100644
index 654be4801..000000000
--- a/components/ido_log/logdbconnection.cpp
+++ /dev/null
@@ -1,37 +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 "ido_log/logdbconnection.h"
-#include "base/logger_fwd.h"
-
-using namespace icinga;
-
-REGISTER_TYPE(LogDbConnection);
-
-LogDbConnection::LogDbConnection(const Dictionary::Ptr& serializedUpdate)
- : DbConnection(serializedUpdate)
-{
- /* We're already "connected" to our database... Let's do this. */
- UpdateAllObjects();
-}
-
-void LogDbConnection::UpdateObject(const DbObject::Ptr& dbobj, DbUpdateType kind)
-{
- Log(LogInformation, "ido_log", "Object '" + dbobj->GetObject()->GetName() + "' was updated.");
-}
diff --git a/components/ido_log/logdbconnection.h b/components/ido_log/logdbconnection.h
deleted file mode 100644
index 290a8b347..000000000
--- a/components/ido_log/logdbconnection.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/******************************************************************************
- * Icinga 2 *
- * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) *
- * *
- * This program is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU General Public License *
- * as published by the Free Software Foundation; either version 2 *
- * of the License, or (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation *
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
- ******************************************************************************/
-
-#ifndef LOGDBCONNECTION_H
-#define LOGDBCONNECTION_H
-
-#include "base/dynamictype.h"
-#include "ido/dbconnection.h"
-
-namespace icinga
-{
-
-/**
- * A MySQL database connection.
- *
- * @ingroup ido
- */
-class LogDbConnection : public DbConnection
-{
-public:
- typedef shared_ptr Ptr;
- typedef weak_ptr WeakPtr;
-
- LogDbConnection(const Dictionary::Ptr& serializedUpdate);
-
- virtual void UpdateObject(const DbObject::Ptr& dbobj, DbUpdateType kind);
-};
-
-}
-
-#endif /* LOGDBCONNECTION_H */
diff --git a/components/ido_mysql/mysqldbconnection.cpp b/components/ido_mysql/mysqldbconnection.cpp
index 24037b554..0a52b25da 100644
--- a/components/ido_mysql/mysqldbconnection.cpp
+++ b/components/ido_mysql/mysqldbconnection.cpp
@@ -58,6 +58,11 @@ MysqlDbConnection::MysqlDbConnection(const Dictionary::Ptr& serializedUpdate)
void MysqlDbConnection::Stop(void)
{
boost::mutex::scoped_lock lock(m_ConnectionMutex);
+
+ if (!m_Connected)
+ return;
+
+ Query("COMMIT");
mysql_close(&m_Connection);
}
@@ -220,9 +225,8 @@ Dictionary::Ptr MysqlDbConnection::FetchRow(MYSQL_RES *result)
for (field = mysql_fetch_field(result), i = 0; field; field = mysql_fetch_field(result), i++) {
Value value;
- if (field) {
+ if (field)
value = String(row[i], row[i] + lengths[i]);
- }
dict->Set(field->name, value);
}
@@ -230,85 +234,147 @@ Dictionary::Ptr MysqlDbConnection::FetchRow(MYSQL_RES *result)
return dict;
}
-void MysqlDbConnection::UpdateObject(const DbObject::Ptr& dbobj, DbUpdateType kind) {
+void MysqlDbConnection::ActivateObject(const DbObject::Ptr& dbobj)
+{
boost::mutex::scoped_lock lock(m_ConnectionMutex);
+ DbReference dbref = GetReference(dbobj);
+ std::ostringstream qbuf;
- /* Check if we can handle updates right now */
- if (!m_Connected)
- return;
+ if (!dbref.IsValid()) {
+ qbuf << "INSERT INTO icinga_objects (instance_id, objecttype_id, name1, name2, is_active) VALUES ("
+ << static_cast(m_InstanceID) << ", " << dbobj->GetType()->GetTypeID() << ", "
+ << "'" << Escape(dbobj->GetName1()) << "', '" << Escape(dbobj->GetName2()) << "', 1)";
+ Query(qbuf.str());
+ SetReference(dbobj, GetInsertID());
+ } else {
+ qbuf << "UPDATE icinga_objects SET is_active = 1 WHERE object_id = " << static_cast(dbref);
+ Query(qbuf.str());
+ }
+}
+
+void MysqlDbConnection::DeactivateObject(const DbObject::Ptr& dbobj)
+{
+ boost::mutex::scoped_lock lock(m_ConnectionMutex);
DbReference dbref = GetReference(dbobj);
- if (kind == DbObjectRemoved) {
- if (!dbref.IsValid())
- return;
+ if (!dbref.IsValid())
+ return;
- std::ostringstream qbuf;
- qbuf << "DELETE FROM icinga_" << dbobj->GetType()->GetTable() << "s WHERE id = " << static_cast(dbref);
- Log(LogWarning, "ido_mysql", "Query: " + qbuf.str());
- }
+ std::ostringstream qbuf;
+ qbuf << "UPDATE icinga_objects SET is_active = 0 WHERE object_id = " << static_cast(dbref);
+ Query(qbuf.str());
- if (kind == DbObjectCreated) {
- std::ostringstream q1buf;
+ SetReference(dbobj, DbReference());
+}
- if (!dbref.IsValid()) {
- q1buf << "INSERT INTO icinga_objects (instance_id, objecttype_id, name1, name2, is_active) VALUES ("
- << static_cast(m_InstanceID) << ", " << dbobj->GetType()->GetTypeID() << ", "
- << "'" << Escape(dbobj->GetName1()) << "', '" << Escape(dbobj->GetName2()) << "', 1)";
- Query(q1buf.str());
- dbref = GetInsertID();
- } else if (kind == DbObjectCreated) {
- q1buf << "UPDATE icinga_objects SET is_active = 1 WHERE object_id = " << static_cast(dbref);
- Query(q1buf.str());
+bool MysqlDbConnection::FieldToString(const String& key, const Value& value, Value *result)
+{
+ *result = value;
+
+ if (value.IsObjectType()) {
+ DbObject::Ptr dbobjcol = DbObject::GetOrCreateByObject(value);
+
+ if (!dbobjcol) {
+ *result = 0;
+ return true;
}
- Dictionary::Ptr fields = dbobj->GetFields();
+ DbReference dbrefcol = GetReference(dbobjcol);
- if (!fields)
- return;
+ if (!dbrefcol.IsValid()) {
+ ActivateObject(dbobjcol);
+ dbrefcol = GetReference(dbobjcol);
+
+ if (!dbrefcol.IsValid())
+ return false;
+ }
+
+ *result = static_cast(dbrefcol);
+ }
+
+ if (key == "instance_id")
+ *result = static_cast(m_InstanceID);
+
+ return true;
+}
+
+void MysqlDbConnection::ExecuteQuery(const DbQuery& query)
+{
+ std::ostringstream qbuf;
+
+ switch (query.Type) {
+ case DbQueryInsert:
+ qbuf << "INSERT INTO " << query.Table;
+ break;
+ case DbQueryUpdate:
+ qbuf << "UPDATE " << query.Table << "SET";
+ break;
+ case DbQueryDelete:
+ qbuf << "DELETE FROM " << query.Table;
+ break;
+ default:
+ ASSERT(!"Invalid query type.");
+ }
+
+ if (query.Type == DbQueryInsert || query.Type == DbQueryUpdate) {
String cols;
String values;
- ObjectLock olock(fields);
+ ObjectLock olock(query.Fields);
String key;
Value value;
- BOOST_FOREACH(boost::tie(key, value), fields) {
- if (value.IsObjectType()) {
- DbObject::Ptr dbobjcol = DbObject::GetOrCreateByObject(value);
+ bool first = true;
+ BOOST_FOREACH(boost::tie(key, value), query.Fields) {
+ if (!FieldToString(key, value, &value))
+ return;
- if (!dbobjcol)
- return;
-
- DbReference dbrefcol = GetReference(dbobjcol);
-
- if (!dbrefcol.IsValid()) {
- UpdateObject(dbobjcol, DbObjectCreated);
-
- dbrefcol = GetReference(dbobjcol);
-
- if (!dbrefcol.IsValid())
- return;
+ if (query.Type == DbQueryInsert) {
+ if (!first) {
+ cols += ", ";
+ values += ", ";
}
- value = static_cast(dbrefcol);
+ cols += key;
+ values += "'" + Convert::ToString(value) + "'";
+ } else {
+ if (!first)
+ qbuf << ", ";
+
+ qbuf << " " << key << " = '" << Escape(value) << "'";
}
- cols += ", " + key;
- values += ", '" + Convert::ToString(value) + "'";
+ if (first)
+ first = false;
}
- std::ostringstream q2buf;
- q2buf << "DELETE FROM icinga_" << dbobj->GetType()->GetTable() << "s WHERE " << dbobj->GetType()->GetTable() << "_object_id = " << static_cast(dbref);
- Query(q2buf.str());
-
- std::ostringstream q3buf;
- q3buf << "INSERT INTO icinga_" << dbobj->GetType()->GetTable()
- << "s (instance_id, " << dbobj->GetType()->GetTable() << "_object_id" << cols << ") VALUES ("
- << static_cast(m_InstanceID) << ", " << static_cast(dbref) << values << ")";
- Query(q3buf.str());
+ if (query.Type == DbQueryInsert)
+ qbuf << " (" << cols << ") VALUES (" << values << ")";
}
- // TODO: Object and status updates
+ if (query.WhereCriteria) {
+ qbuf << " WHERE ";
+
+ ObjectLock olock(query.WhereCriteria);
+
+ String key;
+ Value value;
+ bool first = true;
+ BOOST_FOREACH(boost::tie(key, value), query.WhereCriteria) {
+ if (!FieldToString(Empty, value, &value))
+ return;
+
+ if (!first)
+ qbuf << " AND ";
+
+ qbuf << key << " = '" << Escape(value) << "'";
+
+ if (first)
+ first = false;
+ }
+ }
+
+ Query(qbuf.str());
}
diff --git a/components/ido_mysql/mysqldbconnection.h b/components/ido_mysql/mysqldbconnection.h
index 224b00f48..bc3b2b018 100644
--- a/components/ido_mysql/mysqldbconnection.h
+++ b/components/ido_mysql/mysqldbconnection.h
@@ -43,7 +43,12 @@ public:
MysqlDbConnection(const Dictionary::Ptr& serializedUpdate);
virtual void Stop(void);
- virtual void UpdateObject(const DbObject::Ptr& dbobj, DbUpdateType kind);
+ //virtual void UpdateObject(const DbObject::Ptr& dbobj, DbUpdateType kind);
+
+protected:
+ virtual void ActivateObject(const DbObject::Ptr& dbobj);
+ virtual void DeactivateObject(const DbObject::Ptr& dbobj);
+ virtual void ExecuteQuery(const DbQuery& query);
private:
Attribute m_Host;
@@ -68,6 +73,8 @@ private:
String Escape(const String& s);
Dictionary::Ptr FetchRow(MYSQL_RES *result);
+ bool FieldToString(const String& key, const Value& value, Value *result);
+
void TxTimerHandler(void);
void ReconnectTimerHandler(void);
};
diff --git a/configure.ac b/configure.ac
index 3c74b61a1..af54c31dc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -123,7 +123,6 @@ components/checker/Makefile
components/compat/Makefile
components/delegation/Makefile
components/demo/Makefile
-components/ido_log/Makefile
components/ido_mysql/Makefile
components/livestatus/Makefile
components/notification/Makefile
diff --git a/lib/ido/Makefile.am b/lib/ido/Makefile.am
index 211dc4d0f..51d27cbfc 100644
--- a/lib/ido/Makefile.am
+++ b/lib/ido/Makefile.am
@@ -14,6 +14,8 @@ libido_la_SOURCES = \
dbconnection.h \
dbobject.cpp \
dbobject.h \
+ dbquery.cpp \
+ dbquery.h \
dbreference.cpp \
dbreference.h \
dbtype.cpp \
diff --git a/lib/ido/dbconnection.cpp b/lib/ido/dbconnection.cpp
index 1a155f91b..bd22ed258 100644
--- a/lib/ido/dbconnection.cpp
+++ b/lib/ido/dbconnection.cpp
@@ -29,7 +29,9 @@ DbConnection::DbConnection(const Dictionary::Ptr& serializedUpdate)
void DbConnection::Start(void)
{
- DbObject::OnObjectUpdated.connect(boost::bind(&DbConnection::InternalUpdateObject, this, _1, _2));
+ DbObject::OnRegistered.connect(boost::bind(&DbConnection::ActivateObject, this, _1));
+ DbObject::OnUnregistered.connect(boost::bind(&DbConnection::DeactivateObject, this, _1));
+ DbObject::OnQuery.connect(boost::bind(&DbConnection::ExecuteQuery, this, _1));
}
void DbConnection::SetReference(const DbObject::Ptr& dbobj, const DbReference& dbref)
@@ -52,19 +54,11 @@ DbReference DbConnection::GetReference(const DbObject::Ptr& dbobj) const
return it->second;
}
-void DbConnection::UpdateObject(const DbObject::Ptr&, DbUpdateType)
+void DbConnection::ExecuteQuery(const DbQuery&)
{
/* Default handler does nothing. */
}
-void DbConnection::InternalUpdateObject(const DbObject::Ptr& dbobj, DbUpdateType kind)
-{
- UpdateObject(dbobj, kind);
-
- if (kind == DbObjectRemoved)
- SetReference(dbobj, DbReference());
-}
-
void DbConnection::UpdateAllObjects(void)
{
DynamicType::Ptr type;
@@ -72,8 +66,11 @@ void DbConnection::UpdateAllObjects(void)
BOOST_FOREACH(const DynamicObject::Ptr& object, dt->GetObjects()) {
DbObject::Ptr dbobj = DbObject::GetOrCreateByObject(object);
- if (dbobj)
- UpdateObject(dbobj, DbObjectCreated);
+ if (dbobj) {
+ ActivateObject(dbobj);
+ dbobj->SendConfigUpdate();
+ dbobj->SendStatusUpdate();
+ }
}
}
}
diff --git a/lib/ido/dbconnection.h b/lib/ido/dbconnection.h
index 804527f52..8e6e377bd 100644
--- a/lib/ido/dbconnection.h
+++ b/lib/ido/dbconnection.h
@@ -22,6 +22,7 @@
#include "base/dynamicobject.h"
#include "ido/dbobject.h"
+#include "ido/dbquery.h"
namespace icinga
{
@@ -44,13 +45,13 @@ public:
protected:
virtual void Start(void);
- virtual void UpdateObject(const DbObject::Ptr& dbobj, DbUpdateType kind) = 0;
+ virtual void ExecuteQuery(const DbQuery& query) = 0;
+ virtual void ActivateObject(const DbObject::Ptr& dbobj) = 0;
+ virtual void DeactivateObject(const DbObject::Ptr& dbobj) = 0;
void UpdateAllObjects(void);
private:
- void InternalUpdateObject(const DbObject::Ptr& dbobj, DbUpdateType kind);
-
std::map m_References;
};
diff --git a/lib/ido/dbobject.cpp b/lib/ido/dbobject.cpp
index 419aee5f3..6fb073058 100644
--- a/lib/ido/dbobject.cpp
+++ b/lib/ido/dbobject.cpp
@@ -26,7 +26,9 @@
using namespace icinga;
-boost::signals2::signal DbObject::OnObjectUpdated;
+boost::signals2::signal DbObject::OnRegistered;
+boost::signals2::signal DbObject::OnUnregistered;
+boost::signals2::signal DbObject::OnQuery;
DbObject::DbObject(const shared_ptr& type, const String& name1, const String& name2)
: m_Name1(name1), m_Name2(name2), m_Type(type)
@@ -36,8 +38,8 @@ void DbObject::StaticInitialize(void)
{
DynamicObject::OnRegistered.connect(boost::bind(&DbObject::ObjectRegisteredHandler, _1));
DynamicObject::OnUnregistered.connect(boost::bind(&DbObject::ObjectUnregisteredHandler, _1));
- DynamicObject::OnTransactionClosing.connect(boost::bind(&DbObject::TransactionClosingHandler, _1, _2));
- DynamicObject::OnFlushObject.connect(boost::bind(&DbObject::FlushObjectHandler, _1, _2));
+// DynamicObject::OnTransactionClosing.connect(boost::bind(&DbObject::TransactionClosingHandler, _1, _2));
+// DynamicObject::OnFlushObject.connect(boost::bind(&DbObject::FlushObjectHandler, _1, _2));
}
void DbObject::SetObject(const DynamicObject::Ptr& object)
@@ -65,9 +67,51 @@ DbType::Ptr DbObject::GetType(void) const
return m_Type;
}
-void DbObject::SendUpdate(DbUpdateType kind)
+void DbObject::SendConfigUpdate(void)
{
- OnObjectUpdated(GetSelf(), kind);
+ DbQuery query1;
+ query1.Table = "icinga_" + GetType()->GetTable() + "s";
+ query1.Type = DbQueryDelete;
+ query1.WhereCriteria = boost::make_shared();
+ query1.WhereCriteria->Set(GetType()->GetTable() + "_object_id", GetObject());
+ OnQuery(query1);
+
+ DbQuery query2;
+ query2.Table = "icinga_" + GetType()->GetTable() + "s";
+ query2.Type = DbQueryInsert;
+
+ query2.Fields = GetConfigFields();
+
+ if (!query2.Fields)
+ return;
+
+ query2.Fields->Set(GetType()->GetTable() + "_object_id", GetObject());
+ query2.Fields->Set("instance_id", 0); /* DbConnection class fills in real ID */
+ OnQuery(query2);
+}
+
+void DbObject::SendStatusUpdate(void)
+{
+ DbQuery query1;
+ query1.Table = "icinga_" + GetType()->GetTable() + "status";
+ query1.Type = DbQueryDelete;
+ query1.WhereCriteria = boost::make_shared();
+ query1.WhereCriteria->Set(GetType()->GetTable() + "_object_id", GetObject());
+ OnQuery(query1);
+
+ DbQuery query2;
+ query2.Table = "icinga_" + GetType()->GetTable() + "status";
+ query2.Type = DbQueryInsert;
+
+ query2.Fields = GetStatusFields();
+
+ if (!query2.Fields)
+ return;
+
+ query2.Fields->Set(GetType()->GetTable() + "_object_id", GetObject());
+ query2.Fields->Set("instance_id", 0); /* DbConnection class fills in real ID */
+ query2.Fields->Set("status_update_time", Utility::FormatDateTime("%Y-%m-%d %H:%M:%S", Utility::GetTime()));
+ OnQuery(query2);
}
DbObject::Ptr DbObject::GetOrCreateByObject(const DynamicObject::Ptr& object)
@@ -117,7 +161,10 @@ void DbObject::ObjectRegisteredHandler(const DynamicObject::Ptr& object)
if (!dbobj)
return;
- dbobj->SendUpdate(DbObjectCreated);
+ OnRegistered(dbobj);
+
+ dbobj->SendConfigUpdate();
+ dbobj->SendStatusUpdate();
}
void DbObject::ObjectUnregisteredHandler(const DynamicObject::Ptr& object)
@@ -127,7 +174,8 @@ void DbObject::ObjectUnregisteredHandler(const DynamicObject::Ptr& object)
if (!dbobj)
return;
- dbobj->SendUpdate(DbObjectRemoved);
+ OnUnregistered(dbobj);
+ //dbobj->SendUpdate(DbObjectRemoved);
{
ObjectLock olock(object);
@@ -135,24 +183,24 @@ void DbObject::ObjectUnregisteredHandler(const DynamicObject::Ptr& object)
}
}
-void DbObject::TransactionClosingHandler(double tx, const std::set& modifiedObjects)
-{
- BOOST_FOREACH(const DynamicObject::WeakPtr& wobject, modifiedObjects) {
- DynamicObject::Ptr object = wobject.lock();
-
- if (!object)
- continue;
-
- FlushObjectHandler(tx, object);
- }
-}
-
-void DbObject::FlushObjectHandler(double tx, const DynamicObject::Ptr& object)
-{
- DbObject::Ptr dbobj = GetOrCreateByObject(object);
-
- if (!dbobj)
- return;
-
- dbobj->SendUpdate();
-}
+//void DbObject::TransactionClosingHandler(double tx, const std::set& modifiedObjects)
+//{
+// BOOST_FOREACH(const DynamicObject::WeakPtr& wobject, modifiedObjects) {
+// DynamicObject::Ptr object = wobject.lock();
+//
+// if (!object)
+// continue;
+//
+// FlushObjectHandler(tx, object);
+// }
+//}
+//
+//void DbObject::FlushObjectHandler(double tx, const DynamicObject::Ptr& object)
+//{
+// DbObject::Ptr dbobj = GetOrCreateByObject(object);
+//
+// if (!dbobj)
+// return;
+//
+// dbobj->SendUpdate();
+//}
diff --git a/lib/ido/dbobject.h b/lib/ido/dbobject.h
index d3738febe..c2a124622 100644
--- a/lib/ido/dbobject.h
+++ b/lib/ido/dbobject.h
@@ -20,17 +20,17 @@
#ifndef DBOBJECT_H
#define DBOBJECT_H
-#include "dbreference.h"
+#include "ido/dbreference.h"
+#include "ido/dbquery.h"
#include "base/dynamicobject.h"
#include
namespace icinga
{
-enum DbUpdateType
+enum DbObjectUpdateType
{
DbObjectCreated,
- DbObjectUpdated,
DbObjectRemoved
};
@@ -53,13 +53,17 @@ public:
String GetName2(void) const;
boost::shared_ptr GetType(void) const;
- virtual Dictionary::Ptr GetFields(void) const = 0;
+ virtual Dictionary::Ptr GetConfigFields(void) const = 0;
+ virtual Dictionary::Ptr GetStatusFields(void) const = 0;
static DbObject::Ptr GetOrCreateByObject(const DynamicObject::Ptr& object);
- static boost::signals2::signal OnObjectUpdated;
+ static boost::signals2::signal OnRegistered;
+ static boost::signals2::signal OnUnregistered;
+ static boost::signals2::signal OnQuery;
- void SendUpdate(DbUpdateType kind = DbObjectUpdated);
+ void SendConfigUpdate(void);
+ void SendStatusUpdate(void);
protected:
DbObject(const boost::shared_ptr& type, const String& name1, const String& name2);
@@ -76,8 +80,8 @@ private:
static void ObjectRegisteredHandler(const DynamicObject::Ptr& object);
static void ObjectUnregisteredHandler(const DynamicObject::Ptr& object);
- static void TransactionClosingHandler(double tx, const std::set& modifiedObjects);
- static void FlushObjectHandler(double tx, const DynamicObject::Ptr& object);
+ //static void TransactionClosingHandler(double tx, const std::set& modifiedObjects);
+ //static void FlushObjectHandler(double tx, const DynamicObject::Ptr& object);
friend class DbType;
};
diff --git a/lib/ido/dbtype.h b/lib/ido/dbtype.h
index ebf0bd3bd..005d06f08 100644
--- a/lib/ido/dbtype.h
+++ b/lib/ido/dbtype.h
@@ -32,7 +32,7 @@ namespace icinga
*
* @ingroup ido
*/
-struct DbType : public Object
+class DbType : public Object
{
public:
DECLARE_PTR_TYPEDEFS(DbType);
diff --git a/lib/ido/hostdbobject.cpp b/lib/ido/hostdbobject.cpp
index d51329ee6..160653d2f 100644
--- a/lib/ido/hostdbobject.cpp
+++ b/lib/ido/hostdbobject.cpp
@@ -20,6 +20,9 @@
#include "ido/hostdbobject.h"
#include "ido/dbtype.h"
#include "icinga/host.h"
+#include "icinga/service.h"
+#include "icinga/checkcommand.h"
+#include
using namespace icinga;
@@ -29,12 +32,189 @@ HostDbObject::HostDbObject(const String& name1, const String& name2)
: DbObject(DbType::GetByName("Host"), name1, name2)
{ }
-Dictionary::Ptr HostDbObject::GetFields(void) const
+Dictionary::Ptr HostDbObject::GetConfigFields(void) const
{
Dictionary::Ptr fields = boost::make_shared();
Host::Ptr host = static_pointer_cast(GetObject());
+ Service::Ptr service = host->GetHostCheckService();
+
+ if (!service)
+ return Empty;
+
+ fields->Set("alias", host->GetName());
fields->Set("display_name", host->GetDisplayName());
+ fields->Set("check_command_object_id", service->GetCheckCommand());
+ fields->Set("check_command_args", Empty);
+ fields->Set("check_interval", service->GetCheckInterval() / 60);
+ fields->Set("retry_interval", service->GetRetryInterval() / 60);
+ fields->Set("max_check_attempts", service->GetMaxCheckAttempts());
+
+ fields->Set("address", Empty);
+ fields->Set("address6", Empty);
+ fields->Set("eventhandler_command_object_id", Empty);
+ fields->Set("eventhandler_command_args", Empty);
+ fields->Set("notification_timeperiod_object_id", Empty);
+ fields->Set("check_timeperiod_object_id", Empty);
+ fields->Set("failure_prediction_options", Empty);
+ fields->Set("first_notification_delay", Empty);
+ fields->Set("notification_interval", Empty);
+ fields->Set("notify_on_down", Empty);
+ fields->Set("notify_on_unreachable", Empty);
+ fields->Set("notify_on_recovery", Empty);
+ fields->Set("notify_on_flapping", Empty);
+ fields->Set("notify_on_downtime", Empty);
+ fields->Set("stalk_on_up", Empty);
+ fields->Set("stalk_on_down", Empty);
+ fields->Set("stalk_on_unreachable", Empty);
+ fields->Set("flap_detection_enabled", Empty);
+ fields->Set("flap_detection_on_up", Empty);
+ fields->Set("flap_detection_on_down", Empty);
+ fields->Set("flap_detection_on_unreachable", Empty);
+ fields->Set("low_flap_threshold", Empty);
+ fields->Set("high_flap_threshold", Empty);
+ fields->Set("process_performance_data", Empty);
+ fields->Set("freshness_checks_enabled", Empty);
+ fields->Set("freshness_threshold", Empty);
+ fields->Set("passive_checks_enabled", Empty);
+ fields->Set("event_handler_enabled", Empty);
+ fields->Set("active_checks_enabled", Empty);
+ fields->Set("retain_status_information", 1);
+ fields->Set("retain_nonstatus_information", 1);
+ fields->Set("notifications_enabled", 1);
+ fields->Set("obsess_over_host", 0);
+ fields->Set("failure_prediction_enabled", 0);
+ fields->Set("notes", Empty);
+ fields->Set("notes_url", Empty);
+ fields->Set("action_url", Empty);
+ fields->Set("icon_image", Empty);
+ fields->Set("icon_image_alt", Empty);
+ fields->Set("vrml_image", Empty);
+ fields->Set("statusmap_image", Empty);
+ fields->Set("have_2d_coords", Empty);
+ fields->Set("x_2d", Empty);
+ fields->Set("y_2d", Empty);
+ fields->Set("have_3d_coords", Empty);
+ fields->Set("x_3d", Empty);
+ fields->Set("y_3d", Empty);
+ fields->Set("z_3d", Empty);
+
+ return fields;
+}
+
+Dictionary::Ptr HostDbObject::GetStatusFields(void) const
+{
+ Dictionary::Ptr fields = boost::make_shared();
+ Host::Ptr host = static_pointer_cast(GetObject());
+ Service::Ptr service = host->GetHostCheckService();
+
+ if (!service)
+ return Empty;
+
+ String raw_output;
+ String output;
+ String long_output;
+ String perfdata;
+ double schedule_end = -1;
+
+ String check_period_str;
+ TimePeriod::Ptr check_period = service->GetCheckPeriod();
+ if (check_period)
+ check_period_str = check_period->GetName();
+ else
+ check_period_str = "24x7";
+
+ Dictionary::Ptr cr = service->GetLastCheckResult();
+
+ if (cr) {
+ raw_output = cr->Get("output");
+ size_t line_end = raw_output.Find("\n");
+
+ output = raw_output.SubStr(0, line_end);
+
+ if (line_end > 0 && line_end != String::NPos)
+ long_output = raw_output.SubStr(line_end+1, raw_output.GetLength());
+
+ boost::algorithm::replace_all(output, "\n", "\\n");
+
+ schedule_end = cr->Get("schedule_end");
+
+ perfdata = cr->Get("performance_data_raw");
+ boost::algorithm::replace_all(perfdata, "\n", "\\n");
+ }
+
+ int state = service->GetState();
+
+ if (state > StateUnknown)
+ state = StateUnknown;
+
+// if (type == CompatTypeHost) {
+ if (state == StateOK || state == StateWarning)
+ state = 0; /* UP */
+ else
+ state = 1; /* DOWN */
+
+ if (!host->IsReachable())
+ state = 2; /* UNREACHABLE */
+// }
+
+ double last_notification = 0;
+ double next_notification = 0;
+ int notification_number = 0;
+ BOOST_FOREACH(const Notification::Ptr& notification, service->GetNotifications()) {
+ if (notification->GetLastNotification() > last_notification)
+ last_notification = notification->GetLastNotification();
+
+ if (notification->GetNextNotification() < next_notification)
+ next_notification = notification->GetNextNotification();
+
+ if (notification->GetNotificationNumber() > notification_number)
+ notification_number = notification->GetNotificationNumber();
+ }
+ fields->Set("output", output);
+ fields->Set("long_output", long_output);
+ fields->Set("perfdata", perfdata);
+ fields->Set("current_state", state);
+ fields->Set("has_been_checked", (service->GetLastCheckResult() ? 1 : 0));
+ fields->Set("should_be_scheduled", 1);
+ fields->Set("current_check_attempt", service->GetCurrentCheckAttempt());
+ fields->Set("max_check_attempts", service->GetMaxCheckAttempts());
+ fields->Set("last_check", schedule_end);
+ fields->Set("next_check", service->GetNextCheck());
+ fields->Set("check_type", Empty);
+ fields->Set("last_state_change", Empty);
+ fields->Set("last_hard_state_change", Empty);
+ fields->Set("last_hard_state", Empty);
+ fields->Set("last_time_up", Empty);
+ fields->Set("last_time_down", Empty);
+ fields->Set("last_time_unreachable", Empty);
+ fields->Set("state_type", Empty);
+ fields->Set("last_notification", Empty);
+ fields->Set("next_notification", Empty);
+ fields->Set("no_more_notifications", Empty);
+ fields->Set("notifications_enabled", Empty);
+ fields->Set("problem_has_been_acknowledged", Empty);
+ fields->Set("acknowledgement_type", Empty);
+ fields->Set("current_notification_number", Empty);
+ fields->Set("passive_checks_enabled", Empty);
+ fields->Set("active_checks_enabled", Empty);
+ fields->Set("event_handler_enabled", Empty);
+ fields->Set("flap_detection_enabled", Empty);
+ fields->Set("is_flapping", Empty);
+ fields->Set("percent_state_change", Empty);
+ fields->Set("latency", Empty);
+ fields->Set("execution_time", Empty);
+ fields->Set("scheduled_downtime_depth", Empty);
+ fields->Set("failure_prediction_enabled", Empty);
+ fields->Set("process_performance_data", Empty);
+ fields->Set("obsess_over_host", Empty);
+ fields->Set("modified_host_attributes", Empty);
+ fields->Set("event_handler", Empty);
+ fields->Set("check_command", Empty);
+ fields->Set("normal_check_interval", Empty);
+ fields->Set("retry_check_interval", Empty);
+ fields->Set("check_timeperiod_object_id", Empty);
+
return fields;
}
diff --git a/lib/ido/hostdbobject.h b/lib/ido/hostdbobject.h
index ac9b41fbc..0a58aec1e 100644
--- a/lib/ido/hostdbobject.h
+++ b/lib/ido/hostdbobject.h
@@ -38,7 +38,8 @@ public:
HostDbObject(const String& name1, const String& name2);
- virtual Dictionary::Ptr GetFields(void) const;
+ virtual Dictionary::Ptr GetConfigFields(void) const;
+ virtual Dictionary::Ptr GetStatusFields(void) const;
};
}
diff --git a/lib/ido/servicedbobject.cpp b/lib/ido/servicedbobject.cpp
index 2d9651f99..c8ed7945b 100644
--- a/lib/ido/servicedbobject.cpp
+++ b/lib/ido/servicedbobject.cpp
@@ -20,6 +20,7 @@
#include "ido/servicedbobject.h"
#include "ido/dbtype.h"
#include "icinga/service.h"
+#include "icinga/checkcommand.h"
using namespace icinga;
@@ -29,12 +30,111 @@ ServiceDbObject::ServiceDbObject(const String& name1, const String& name2)
: DbObject(DbType::GetByName("Service"), name1, name2)
{ }
-Dictionary::Ptr ServiceDbObject::GetFields(void) const
+Dictionary::Ptr ServiceDbObject::GetConfigFields(void) const
{
Dictionary::Ptr fields = boost::make_shared();
Service::Ptr service = static_pointer_cast(GetObject());
fields->Set("display_name", service->GetDisplayName());
+ fields->Set("check_command_object_id", service->GetCheckCommand());
+ fields->Set("check_command_args", Empty);
+ fields->Set("eventhandler_command_object_id", Empty);
+ fields->Set("eventhandler_command_args", Empty);
+ fields->Set("notification_timeperiod_object_id", Empty);
+ fields->Set("check_timeperiod_object_id", Empty);
+ fields->Set("failure_prediction_options", Empty);
+ fields->Set("check_interval", service->GetCheckInterval() * 60);
+ fields->Set("retry_interval", service->GetRetryInterval() * 60);
+ fields->Set("max_check_attempts", service->GetMaxCheckAttempts());
+ fields->Set("first_notification_delay", Empty);
+ fields->Set("notification_interval", Empty);
+ fields->Set("notify_on_warning", Empty);
+ fields->Set("notify_on_unknown", Empty);
+ fields->Set("notify_on_critical", Empty);
+ fields->Set("notify_on_recovery", Empty);
+ fields->Set("notify_on_flapping", Empty);
+ fields->Set("notify_on_downtime", Empty);
+ fields->Set("stalk_on_ok", 0);
+ fields->Set("stalk_on_warning", 0);
+ fields->Set("stalk_on_unknown", 0);
+ fields->Set("stalk_on_critical", 0);
+ fields->Set("is_volatile", Empty);
+ fields->Set("flap_detection_enabled", Empty);
+ fields->Set("flap_detection_on_ok", Empty);
+ fields->Set("flap_detection_on_warning", Empty);
+ fields->Set("flap_detection_on_unknown", Empty);
+ fields->Set("flap_detection_on_critical", Empty);
+ fields->Set("low_flap_threshold", Empty);
+ fields->Set("high_flap_threshold", Empty);
+ fields->Set("process_performance_data", Empty);
+ fields->Set("freshness_checks_enabled", Empty);
+ fields->Set("freshness_threshold", Empty);
+ fields->Set("passive_checks_enabled", Empty);
+ fields->Set("event_handler_enabled", Empty);
+ fields->Set("active_checks_enabled", Empty);
+ fields->Set("retain_status_information", Empty);
+ fields->Set("retain_nonstatus_information", Empty);
+ fields->Set("notifications_enabled", Empty);
+ fields->Set("obsess_over_service", Empty);
+ fields->Set("failure_prediction_enabled", Empty);
+ fields->Set("notes", Empty);
+ fields->Set("notes_url", Empty);
+ fields->Set("action_url", Empty);
+ fields->Set("icon_image", Empty);
+ fields->Set("icon_image_alt", Empty);
return fields;
}
+
+Dictionary::Ptr ServiceDbObject::GetStatusFields(void) const
+{
+ Dictionary::Ptr fields = boost::make_shared();
+ Service::Ptr service = static_pointer_cast(GetObject());
+
+ fields->Set("output", Empty);
+ fields->Set("long_output", Empty);
+ fields->Set("perfdata", Empty);
+ fields->Set("current_state", Empty);
+ fields->Set("has_been_checked", Empty);
+ fields->Set("should_be_scheduled", Empty);
+ fields->Set("current_check_attempt", Empty);
+ fields->Set("max_check_attempts", Empty);
+ fields->Set("last_check", Empty);
+ fields->Set("next_check", Empty);
+ fields->Set("check_type", Empty);
+ fields->Set("last_state_change", Empty);
+ fields->Set("last_hard_state_change", Empty);
+ fields->Set("last_hard_state", Empty);
+ fields->Set("last_time_ok", Empty);
+ fields->Set("last_time_warning", Empty);
+ fields->Set("last_time_unknown", Empty);
+ fields->Set("last_time_critical", Empty);
+ fields->Set("state_type", Empty);
+ fields->Set("last_notification", Empty);
+ fields->Set("next_notification", Empty);
+ fields->Set("no_more_notifications", Empty);
+ fields->Set("notifications_enabled", Empty);
+ fields->Set("problem_has_been_acknowledged", Empty);
+ fields->Set("acknowledgement_type", Empty);
+ fields->Set("current_notification_number", Empty);
+ fields->Set("passive_checks_enabled", Empty);
+ fields->Set("active_checks_enabled", Empty);
+ fields->Set("event_handler_enabled", Empty);
+ fields->Set("flap_detection_enabled", Empty);
+ fields->Set("is_flapping", Empty);
+ fields->Set("percent_state_change", Empty);
+ fields->Set("latency", Empty);
+ fields->Set("execution_time", Empty);
+ fields->Set("scheduled_downtime_depth", Empty);
+ fields->Set("failure_prediction_enabled", Empty);
+ fields->Set("process_performance_data", Empty);
+ fields->Set("obsess_over_service", Empty);
+ fields->Set("modified_service_attributes", Empty);
+ fields->Set("event_handler", Empty);
+ fields->Set("check_command", Empty);
+ fields->Set("normal_check_interval", Empty);
+ fields->Set("retry_check_interval", Empty);
+ fields->Set("check_timeperiod_object_id", Empty);
+
+ return fields;
+}
\ No newline at end of file
diff --git a/lib/ido/servicedbobject.h b/lib/ido/servicedbobject.h
index 1dff03c9d..d6b060888 100644
--- a/lib/ido/servicedbobject.h
+++ b/lib/ido/servicedbobject.h
@@ -38,7 +38,8 @@ public:
ServiceDbObject(const String& name1, const String& name2);
- virtual Dictionary::Ptr GetFields(void) const;
+ virtual Dictionary::Ptr GetConfigFields(void) const;
+ virtual Dictionary::Ptr GetStatusFields(void) const;
};
}