From 28726e5025bb470b7f529753cb83851af7b2304d Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Wed, 24 Jul 2013 10:55:04 +0200 Subject: [PATCH] Implement status updates for services. --- components/ido_mysql/mysqldbconnection.cpp | 9 ++- components/ido_mysql/mysqldbconnection.h | 1 + lib/base/dynamicobject.cpp | 3 + lib/base/dynamicobject.h | 1 + lib/ido/dbobject.cpp | 85 +++++++++++++++------- lib/ido/dbobject.h | 9 +++ lib/ido/servicedbobject.cpp | 5 ++ lib/ido/servicedbobject.h | 2 + 8 files changed, 88 insertions(+), 27 deletions(-) diff --git a/components/ido_mysql/mysqldbconnection.cpp b/components/ido_mysql/mysqldbconnection.cpp index 2e79ec0c2..bcf9f5b2c 100644 --- a/components/ido_mysql/mysqldbconnection.cpp +++ b/components/ido_mysql/mysqldbconnection.cpp @@ -244,7 +244,11 @@ Dictionary::Ptr MysqlDbConnection::FetchRow(MYSQL_RES *result) void MysqlDbConnection::ActivateObject(const DbObject::Ptr& dbobj) { boost::mutex::scoped_lock lock(m_ConnectionMutex); + InternalActivateObject(dbobj); +} +void MysqlDbConnection::InternalActivateObject(const DbObject::Ptr& dbobj) +{ if (!m_Connected) return; @@ -282,6 +286,7 @@ void MysqlDbConnection::DeactivateObject(const DbObject::Ptr& dbobj) SetReference(dbobj, DbReference()); } +/* caller must hold m_ConnectionMutex */ bool MysqlDbConnection::FieldToEscapedString(const String& key, const Value& value, Value *result) { if (key == "instance_id") { @@ -300,7 +305,7 @@ bool MysqlDbConnection::FieldToEscapedString(const String& key, const Value& val DbReference dbrefcol = GetReference(dbobjcol); if (!dbrefcol.IsValid()) { - ActivateObject(dbobjcol); + InternalActivateObject(dbobjcol); dbrefcol = GetReference(dbobjcol); @@ -310,7 +315,7 @@ bool MysqlDbConnection::FieldToEscapedString(const String& key, const Value& val *result = static_cast(dbrefcol); } else if (DbValue::IsTimestamp(value)) { - double ts = DbValue::ExtractValue(value); + long ts = DbValue::ExtractValue(value); std::ostringstream msgbuf; msgbuf << "FROM_UNIXTIME(" << ts << ")"; *result = Value(msgbuf.str()); diff --git a/components/ido_mysql/mysqldbconnection.h b/components/ido_mysql/mysqldbconnection.h index 6384ffb48..628615582 100644 --- a/components/ido_mysql/mysqldbconnection.h +++ b/components/ido_mysql/mysqldbconnection.h @@ -74,6 +74,7 @@ private: Dictionary::Ptr FetchRow(MYSQL_RES *result); bool FieldToEscapedString(const String& key, const Value& value, Value *result); + void InternalActivateObject(const DbObject::Ptr& dbobj); void TxTimerHandler(void); void ReconnectTimerHandler(void); diff --git a/lib/base/dynamicobject.cpp b/lib/base/dynamicobject.cpp index 8bf1ef91c..659e23acf 100644 --- a/lib/base/dynamicobject.cpp +++ b/lib/base/dynamicobject.cpp @@ -47,6 +47,7 @@ boost::signals2::signal DynamicObject::OnRegis boost::signals2::signal DynamicObject::OnUnregistered; boost::signals2::signal&)> DynamicObject::OnTransactionClosing; boost::signals2::signal DynamicObject::OnFlushObject; +boost::signals2::signal&)> DynamicObject::OnAttributesChanged; DynamicObject::DynamicObject(const Dictionary::Ptr& serializedObject) : m_ConfigTx(0), m_LocalTx(0), m_Registered(false) @@ -627,6 +628,8 @@ void DynamicObject::NewTx(void) attrs.swap(object->m_ModifiedAttributes); } + OnAttributesChanged(object, attrs); + BOOST_FOREACH(const String& attr, attrs) { object->OnAttributeChanged(attr); } diff --git a/lib/base/dynamicobject.h b/lib/base/dynamicobject.h index 39e96e238..ba6b419d4 100644 --- a/lib/base/dynamicobject.h +++ b/lib/base/dynamicobject.h @@ -69,6 +69,7 @@ public: static boost::signals2::signal OnUnregistered; static boost::signals2::signal&)> OnTransactionClosing; static boost::signals2::signal OnFlushObject; + static boost::signals2::signal&)> OnAttributesChanged; Value InvokeMethod(const String& method, const std::vector& arguments); diff --git a/lib/ido/dbobject.cpp b/lib/ido/dbobject.cpp index 4d1e9920c..c19aad7b9 100644 --- a/lib/ido/dbobject.cpp +++ b/lib/ido/dbobject.cpp @@ -23,6 +23,7 @@ #include "base/dynamictype.h" #include "base/objectlock.h" #include "base/utility.h" +#include "base/logger_fwd.h" #include using namespace icinga; @@ -32,15 +33,14 @@ 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) + : m_Name1(name1), m_Name2(name2), m_Type(type), m_LastConfigUpdate(0), m_LastStatusUpdate(0) { } 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::OnAttributesChanged.connect(boost::bind(&DbObject::AttributesChangedHandler, _1, _2)); } void DbObject::SetObject(const DynamicObject::Ptr& object) @@ -90,6 +90,8 @@ void DbObject::SendConfigUpdate(void) query2.Fields->Set("instance_id", 0); /* DbConnection class fills in real ID */ query2.Fields->Set("config_type", 1); OnQuery(query2); + + m_LastConfigUpdate = Utility::GetTime(); } void DbObject::SendStatusUpdate(void) @@ -114,6 +116,37 @@ void DbObject::SendStatusUpdate(void) 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); + + m_LastStatusUpdate = Utility::GetTime(); +} + +double DbObject::GetLastConfigUpdate(void) const +{ + return m_LastConfigUpdate; +} + +double DbObject::GetLastStatusUpdate(void) const +{ + return m_LastStatusUpdate; +} + +bool DbObject::IsConfigAttribute(const String& attribute) const +{ + DynamicObject::Ptr object = GetObject(); + ObjectLock olock(object); + DynamicObject::AttributeConstIterator it; + + it = object->GetAttributes().find(attribute); + + if (it == object->GetAttributes().end()) + return false; + + return (it->second.GetType() == Attribute_Config); +} + +bool DbObject::IsStatusAttribute(const String&) const +{ + return false; } DbObject::Ptr DbObject::GetOrCreateByObject(const DynamicObject::Ptr& object) @@ -145,7 +178,7 @@ DbObject::Ptr DbObject::GetOrCreateByObject(const DynamicObject::Ptr& object) name1 = object->GetName(); } - dbobj = dbtype->GetOrCreateObjectByName(object->GetName(), String()); + dbobj = dbtype->GetOrCreateObjectByName(name1, name2); { ObjectLock olock(object); @@ -185,24 +218,26 @@ 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::AttributesChangedHandler(const DynamicObject::Ptr& object, const std::set& attributes) +{ + DbObject::Ptr dbobj = GetOrCreateByObject(object); + + if (!dbobj) + return; + + bool configUpdate = false, statusUpdate = false; + + BOOST_FOREACH(const String& attribute, attributes) { + if (!configUpdate && dbobj->IsConfigAttribute(attribute)) + configUpdate = true; + + if (!statusUpdate && dbobj->IsStatusAttribute(attribute)) + statusUpdate = true; + } + + if (configUpdate) + dbobj->SendConfigUpdate(); + + if (statusUpdate) + dbobj->SendStatusUpdate(); +} diff --git a/lib/ido/dbobject.h b/lib/ido/dbobject.h index c2a124622..e1b351904 100644 --- a/lib/ido/dbobject.h +++ b/lib/ido/dbobject.h @@ -65,14 +65,22 @@ public: void SendConfigUpdate(void); void SendStatusUpdate(void); + double GetLastConfigUpdate(void) const; + double GetLastStatusUpdate(void) const; + protected: DbObject(const boost::shared_ptr& type, const String& name1, const String& name2); + virtual bool IsConfigAttribute(const String& attribute) const; + virtual bool IsStatusAttribute(const String& attribute) const; + private: String m_Name1; String m_Name2; boost::shared_ptr m_Type; DynamicObject::Ptr m_Object; + double m_LastConfigUpdate; + double m_LastStatusUpdate; friend boost::shared_ptr boost::make_shared<>(const icinga::String&, const icinga::String&); @@ -80,6 +88,7 @@ private: static void ObjectRegisteredHandler(const DynamicObject::Ptr& object); static void ObjectUnregisteredHandler(const DynamicObject::Ptr& object); + static void AttributesChangedHandler(const DynamicObject::Ptr& object, const std::set& attributes); //static void TransactionClosingHandler(double tx, const std::set& modifiedObjects); //static void FlushObjectHandler(double tx, const DynamicObject::Ptr& object); diff --git a/lib/ido/servicedbobject.cpp b/lib/ido/servicedbobject.cpp index 7d61bd9a6..576f27341 100644 --- a/lib/ido/servicedbobject.cpp +++ b/lib/ido/servicedbobject.cpp @@ -145,4 +145,9 @@ Dictionary::Ptr ServiceDbObject::GetStatusFields(void) const return fields; +} + +bool ServiceDbObject::IsStatusAttribute(const String& attribute) const +{ + return (attribute == "last_result"); } \ No newline at end of file diff --git a/lib/ido/servicedbobject.h b/lib/ido/servicedbobject.h index d6b060888..28a98b92a 100644 --- a/lib/ido/servicedbobject.h +++ b/lib/ido/servicedbobject.h @@ -40,6 +40,8 @@ public: virtual Dictionary::Ptr GetConfigFields(void) const; virtual Dictionary::Ptr GetStatusFields(void) const; + + virtual bool IsStatusAttribute(const String& attribute) const; }; } -- 2.40.0