]> granicus.if.org Git - icinga2/commitdiff
Convert Comment/Downtime to config objects
authorGunnar Beutner <gunnar@beutner.name>
Thu, 20 Aug 2015 15:18:48 +0000 (17:18 +0200)
committerMichael Friedrich <michael.friedrich@netways.de>
Wed, 28 Oct 2015 16:56:29 +0000 (17:56 +0100)
fixes #9777

85 files changed:
lib/base/application.cpp
lib/base/application.hpp
lib/base/configobject.cpp
lib/base/configobject.hpp
lib/base/configobject.ti
lib/base/configwriter.cpp
lib/base/configwriter.hpp
lib/base/filelogger.cpp
lib/base/filelogger.hpp
lib/base/logger.cpp
lib/base/logger.hpp
lib/base/streamlogger.cpp
lib/base/streamlogger.hpp
lib/checker/checkercomponent.cpp
lib/checker/checkercomponent.hpp
lib/compat/checkresultreader.cpp
lib/compat/checkresultreader.hpp
lib/compat/compatlogger.cpp
lib/compat/compatlogger.hpp
lib/compat/externalcommandlistener.cpp
lib/compat/externalcommandlistener.hpp
lib/compat/statusdatawriter.cpp
lib/compat/statusdatawriter.hpp
lib/config/configitem.cpp
lib/config/configitem.hpp
lib/db_ido/dbconnection.cpp
lib/db_ido/dbconnection.hpp
lib/db_ido/dbevents.cpp
lib/db_ido/dbevents.hpp
lib/demo/demo.cpp
lib/demo/demo.hpp
lib/icinga/apiactions.cpp
lib/icinga/apievents.cpp
lib/icinga/apievents.hpp
lib/icinga/checkable-comment.cpp
lib/icinga/checkable-downtime.cpp
lib/icinga/checkable-notification.cpp
lib/icinga/checkable.cpp
lib/icinga/checkable.hpp
lib/icinga/checkable.ti
lib/icinga/clusterevents.cpp
lib/icinga/clusterevents.hpp
lib/icinga/comment.cpp
lib/icinga/comment.hpp
lib/icinga/comment.ti
lib/icinga/dependency.cpp
lib/icinga/dependency.hpp
lib/icinga/downtime.cpp
lib/icinga/downtime.hpp
lib/icinga/downtime.ti
lib/icinga/externalcommandprocessor.cpp
lib/icinga/host.cpp
lib/icinga/host.hpp
lib/icinga/icingastatuswriter.cpp
lib/icinga/icingastatuswriter.hpp
lib/icinga/notification.cpp
lib/icinga/notification.hpp
lib/icinga/scheduleddowntime.cpp
lib/icinga/scheduleddowntime.hpp
lib/icinga/timeperiod.cpp
lib/icinga/timeperiod.hpp
lib/icinga/user.cpp
lib/icinga/user.hpp
lib/livestatus/commentstable.cpp
lib/livestatus/downtimestable.cpp
lib/livestatus/hoststable.cpp
lib/livestatus/livestatuslistener.cpp
lib/livestatus/livestatuslistener.hpp
lib/livestatus/servicestable.cpp
lib/notification/notificationcomponent.cpp
lib/notification/notificationcomponent.hpp
lib/perfdata/gelfwriter.cpp
lib/perfdata/gelfwriter.hpp
lib/perfdata/graphitewriter.cpp
lib/perfdata/graphitewriter.hpp
lib/perfdata/opentsdbwriter.cpp
lib/perfdata/opentsdbwriter.hpp
lib/perfdata/perfdatawriter.cpp
lib/perfdata/perfdatawriter.hpp
lib/remote/apilistener.cpp
lib/remote/apilistener.hpp
lib/remote/configobjectutility.cpp
lib/remote/configobjectutility.hpp
lib/remote/createobjecthandler.cpp
tools/mkclass/classcompiler.cpp

index 0c8aef26608100002d822ca53c392995f928a462..5cc81d3c06b989046a3ce488b6cec01781e9205e 100644 (file)
@@ -78,7 +78,7 @@ void Application::OnConfigLoaded(void)
 /**
  * Destructor for the application class.
  */
-void Application::Stop(void)
+void Application::Stop(bool runtimeRemoved)
 {
        m_ShuttingDown = true;
 
@@ -102,7 +102,7 @@ void Application::Stop(void)
        } else
                ClosePidFile(true);
 
-       ObjectImpl<Application>::Stop();
+       ObjectImpl<Application>::Stop(runtimeRemoved);
 }
 
 Application::~Application(void)
index 3906f2efbb4cc3957c7173b5bc6c79a641e39dbd..8f908dfacc53f5bc425d42d2fad2e40d07dc0e9f 100644 (file)
@@ -138,7 +138,7 @@ public:
 
 protected:
        virtual void OnConfigLoaded(void) override;
-       virtual void Stop(void) override;
+       virtual void Stop(bool runtimeRemoved) override;
 
        void RunEventLoop(void);
 
index 354a5eafab3c29c48a96aa46f5ea7abd251d1a60..deb746752ab036d7629b7bba42c6cc071705a479 100644 (file)
@@ -374,9 +374,9 @@ void ConfigObject::Unregister(void)
        dtype->UnregisterObject(this);
 }
 
-void ConfigObject::Start(void)
+void ConfigObject::Start(bool runtimeCreated)
 {
-       ObjectImpl<ConfigObject>::Start();
+       ObjectImpl<ConfigObject>::Start(runtimeCreated);
 
        ASSERT(!OwnsLock());
        ObjectLock olock(this);
@@ -384,13 +384,13 @@ void ConfigObject::Start(void)
        SetStartCalled(true);
 }
 
-void ConfigObject::Activate(void)
+void ConfigObject::Activate(bool runtimeCreated)
 {
        CONTEXT("Activating object '" + GetName() + "' of type '" + GetType()->GetName() + "'");
 
        ASSERT(!OwnsLock());
 
-       Start();
+       Start(runtimeCreated);
 
        ASSERT(GetStartCalled());
 
@@ -405,9 +405,9 @@ void ConfigObject::Activate(void)
        NotifyActive();
 }
 
-void ConfigObject::Stop(void)
+void ConfigObject::Stop(bool runtimeRemoved)
 {
-       ObjectImpl<ConfigObject>::Stop();
+       ObjectImpl<ConfigObject>::Stop(runtimeRemoved);
 
        ASSERT(!OwnsLock());
        ObjectLock olock(this);
@@ -415,7 +415,7 @@ void ConfigObject::Stop(void)
        SetStopCalled(true);
 }
 
-void ConfigObject::Deactivate(void)
+void ConfigObject::Deactivate(bool runtimeRemoved)
 {
        CONTEXT("Deactivating object '" + GetName() + "' of type '" + GetType()->GetName() + "'");
 
@@ -432,7 +432,7 @@ void ConfigObject::Deactivate(void)
                SetActive(false, true);
        }
 
-       Stop();
+       Stop(runtimeRemoved);
 
        ASSERT(GetStopCalled());
 
index ba2d04285bb050c241ab17ffe87ab8c83508ae0a..1991d5c6ea1b05615dc749155ba20b9bd987d1f7 100644 (file)
@@ -60,12 +60,12 @@ public:
        void Register(void);
        void Unregister(void);
 
-       void Activate(void);
-       void Deactivate(void);
+       void Activate(bool runtimeCreated = false);
+       void Deactivate(bool runtimeRemoved = false);
        void SetAuthority(bool authority);
 
-       virtual void Start(void) override;
-       virtual void Stop(void) override;
+       virtual void Start(bool runtimeCreated = false) override;
+       virtual void Stop(bool runtimeRemoved = false) override;
 
        virtual void Pause(void);
        virtual void Resume(void);
index ba19b7bc15d8594010abacc6606bb40e07840f3c..fdb01fd2707b91605925c20106a7876fb0132a99 100644 (file)
@@ -55,10 +55,10 @@ public:
                m_DebugInfo = di;
        }
 
-       inline virtual void Start(void)
+       inline virtual void Start(bool runtimeCreated)
        { }
 
-       inline virtual void Stop(void)
+       inline virtual void Stop(bool runtimeRemoved)
        { }
 
 private:
index ec55146363fa4cc0b2547735e2bb2cda8165a55e..cc58ecdee36cd4dd1635f0a84e76815a5ea46113 100644 (file)
@@ -165,7 +165,7 @@ void ConfigWriter::EmitIdentifier(std::ostream& fp, const String& identifier, bo
 }
 
 void ConfigWriter::EmitConfigItem(std::ostream& fp, const String& type, const String& name, bool isTemplate,
-    const Array::Ptr& imports, const Dictionary::Ptr& attrs)
+    bool ignoreOnError, const Array::Ptr& imports, const Dictionary::Ptr& attrs)
 {
        if (isTemplate)
                fp << "template ";
@@ -175,6 +175,10 @@ void ConfigWriter::EmitConfigItem(std::ostream& fp, const String& type, const St
        EmitIdentifier(fp, type, false);
        fp << " ";
        EmitString(fp, name);
+
+       if (ignoreOnError)
+               fp << " ignore_on_error";
+
        fp << " ";
        EmitScope(fp, 1, attrs, imports);
 }
index fcee04ab9b6e719bce42f5c2f79d8d9cf4ef9d5a..9d933be3c5d41d09289707cc115a837b0c884222 100644 (file)
@@ -50,7 +50,7 @@ public:
 
        static void EmitIdentifier(std::ostream& fp, const String& identifier, bool inAssignment);
        static void EmitConfigItem(std::ostream& fp, const String& type, const String& name, bool isTemplate,
-           const Array::Ptr& imports, const Dictionary::Ptr& attrs);
+           bool ignoreOnError, const Array::Ptr& imports, const Dictionary::Ptr& attrs);
 
        static void EmitComment(std::ostream& fp, const String& text);
        static void EmitFunctionCall(std::ostream& fp, const String& name, const Array::Ptr& arguments);
index 7fa3197f055cb639381e75f6377fbe418ed26cae..bad2b49fd50d8c2eda87b3b8bc7f99f2beee2c42 100644 (file)
@@ -44,9 +44,9 @@ void FileLogger::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&)
 /**
  * Constructor for the FileLogger class.
  */
-void FileLogger::Start(void)
+void FileLogger::Start(bool runtimeCreated)
 {
-       ObjectImpl<FileLogger>::Start();
+       ObjectImpl<FileLogger>::Start(runtimeCreated);
 
        ReopenLogFile();
 
index 026e101b221b738a2166dc72014ed0c0ed0a3279..f6e5998c1321a87837c624030fb3d384c202c486 100644 (file)
@@ -39,7 +39,7 @@ public:
 
        static void StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata);
 
-       virtual void Start(void) override;
+       virtual void Start(bool runtimeCreated) override;
 
 private:
        void ReopenLogFile(void);
index c7cf16169a892d75f6ffc373fa177a9d4f673681..eadb2c7166867a78ab27a5b3526e9d4a4f4e0b35 100644 (file)
@@ -52,22 +52,22 @@ void Logger::StaticInitialize(void)
 /**
  * Constructor for the Logger class.
  */
-void Logger::Start(void)
+void Logger::Start(bool runtimeCreated)
 {
-       ObjectImpl<Logger>::Start();
+       ObjectImpl<Logger>::Start(runtimeCreated);
 
        boost::mutex::scoped_lock lock(m_Mutex);
        m_Loggers.insert(this);
 }
 
-void Logger::Stop(void)
+void Logger::Stop(bool runtimeRemoved)
 {
        {
                boost::mutex::scoped_lock lock(m_Mutex);
                m_Loggers.erase(this);
        }
 
-       ObjectImpl<Logger>::Stop();
+       ObjectImpl<Logger>::Stop(runtimeRemoved);
 }
 
 std::set<Logger::Ptr> Logger::GetLoggers(void)
index 7877e1961779d78b319f366bd24acea929d40e02..5ca5ef9a92a77914396f8825b555c3d90bd10137 100644 (file)
@@ -93,8 +93,8 @@ public:
        static void StaticInitialize(void);
 
 protected:
-       virtual void Start(void) override;
-       virtual void Stop(void) override;
+       virtual void Start(bool runtimeCreated) override;
+       virtual void Stop(bool runtimeRemoved) override;
 
 private:
        static boost::mutex m_Mutex;
index 0791a2ad43921eaa3331ab252a0dc01f9a651ed6..0839b19e9bc2abdb568e12b624a94e65027b78d6 100644 (file)
@@ -37,9 +37,9 @@ StreamLogger::StreamLogger(void)
        : m_Stream(NULL), m_OwnsStream(false)
 { }
 
-void StreamLogger::Stop(void)
+void StreamLogger::Stop(bool runtimeRemoved)
 {
-       ObjectImpl<StreamLogger>::Stop();
+       ObjectImpl<StreamLogger>::Stop(runtimeRemoved);
 
        // make sure we flush the log data on shutdown, even if we don't call the destructor
        if (m_Stream)
index 68d70f9fba6022d3799f86675ebd1793826e2b35..70bcb809b6ddaab20588cfb763f9321a35199bda 100644 (file)
@@ -40,7 +40,7 @@ public:
 
        StreamLogger(void);
 
-       virtual void Stop(void) override;
+       virtual void Stop(bool runtimeRemoved) override;
        ~StreamLogger(void);
 
        void BindStream(std::ostream *stream, bool ownsStream);
index dd752256238bed57ec410ae3465fe9be0ba8a1da..416c9cfbf4329c03000df07c265fd7ee11b2405b 100644 (file)
@@ -72,9 +72,9 @@ void CheckerComponent::OnConfigLoaded(void)
        Checkable::OnNextCheckChanged.connect(bind(&CheckerComponent::NextCheckChangedHandler, this, _1));
 }
 
-void CheckerComponent::Start(void)
+void CheckerComponent::Start(bool runtimeCreated)
 {
-       ObjectImpl<CheckerComponent>::Start();
+       ObjectImpl<CheckerComponent>::Start(runtimeCreated);
 
        m_Thread = boost::thread(boost::bind(&CheckerComponent::CheckThreadProc, this));
 
@@ -84,7 +84,7 @@ void CheckerComponent::Start(void)
        m_ResultTimer->Start();
 }
 
-void CheckerComponent::Stop(void)
+void CheckerComponent::Stop(bool runtimeRemoved)
 {
        Log(LogInformation, "CheckerComponent", "Checker stopped.");
 
@@ -97,7 +97,7 @@ void CheckerComponent::Stop(void)
        m_ResultTimer->Stop();
        m_Thread.join();
 
-       ObjectImpl<CheckerComponent>::Stop();
+       ObjectImpl<CheckerComponent>::Stop(runtimeRemoved);
 }
 
 void CheckerComponent::CheckThreadProc(void)
index 21389f8e73437d3a3154d0b82e55dc643f905a43..8ccee6cb63ad6d5ee6edca09f952c8c918fd1682 100644 (file)
@@ -71,8 +71,8 @@ public:
        CheckerComponent(void);
 
        virtual void OnConfigLoaded(void) override;
-       virtual void Start(void) override;
-       virtual void Stop(void) override;
+       virtual void Start(bool runtimeCreated) override;
+       virtual void Stop(bool runtimeRemoved) override;
 
        static void StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata);
        unsigned long GetIdleCheckables(void);
index ba9c4ae86ce3f44a456ac5ae5e12597ce4c6d532..423c891d1233439fe287e6bc66a1e22e16fcc20b 100644 (file)
@@ -54,9 +54,9 @@ void CheckResultReader::StatsFunc(const Dictionary::Ptr& status, const Array::Pt
 /**
  * @threadsafety Always.
  */
-void CheckResultReader::Start(void)
+void CheckResultReader::Start(bool runtimeCreated)
 {
-       ObjectImpl<CheckResultReader>::Start();
+       ObjectImpl<CheckResultReader>::Start(runtimeCreated);
 
        m_ReadTimer = new Timer();
        m_ReadTimer->OnTimerExpired.connect(boost::bind(&CheckResultReader::ReadTimerHandler, this));
index 15d6f52ef339642d7c781170fc40e3a4c8090be8..ed66e598ce261ab9524fa76a682a13e71ceac954 100644 (file)
@@ -41,7 +41,7 @@ public:
        static void StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata);
 
 protected:
-       virtual void Start(void) override;
+       virtual void Start(bool runtimeCreated) override;
 
 private:
        Timer::Ptr m_ReadTimer;
index 46692088e233bbba3d759380acbb6d023b4814e7..3ac0e86986d0aa55b69d29e4387c763254ec6669 100644 (file)
@@ -57,14 +57,14 @@ void CompatLogger::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&)
 /**
  * @threadsafety Always.
  */
-void CompatLogger::Start(void)
+void CompatLogger::Start(bool runtimeCreated)
 {
-       ObjectImpl<CompatLogger>::Start();
+       ObjectImpl<CompatLogger>::Start(runtimeCreated);
 
        Checkable::OnNewCheckResult.connect(bind(&CompatLogger::CheckResultHandler, this, _1, _2));
        Checkable::OnNotificationSentToUser.connect(bind(&CompatLogger::NotificationSentHandler, this, _1, _2, _3, _4, _5, _6, _7, _8));
-       Checkable::OnDowntimeTriggered.connect(boost::bind(&CompatLogger::TriggerDowntimeHandler, this, _1, _2));
-       Checkable::OnDowntimeRemoved.connect(boost::bind(&CompatLogger::RemoveDowntimeHandler, this, _1, _2));
+       Downtime::OnDowntimeTriggered.connect(boost::bind(&CompatLogger::TriggerDowntimeHandler, this, _1));
+       Downtime::OnDowntimeRemoved.connect(boost::bind(&CompatLogger::RemoveDowntimeHandler, this, _1));
        Checkable::OnEventCommandExecuted.connect(bind(&CompatLogger::EventCommandHandler, this, _1));
        
        Checkable::OnFlappingChanged.connect(boost::bind(&CompatLogger::FlappingChangedHandler, this, _1));
@@ -147,11 +147,11 @@ void CompatLogger::CheckResultHandler(const Checkable::Ptr& checkable, const Che
 /**
  * @threadsafety Always.
  */
-void CompatLogger::TriggerDowntimeHandler(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime)
+void CompatLogger::TriggerDowntimeHandler(const Downtime::Ptr& downtime)
 {
        Host::Ptr host;
        Service::Ptr service;
-       tie(host, service) = GetHostService(checkable);
+       tie(host, service) = GetHostService(downtime->GetCheckable());
 
        if (!downtime)
                return;
@@ -183,11 +183,11 @@ void CompatLogger::TriggerDowntimeHandler(const Checkable::Ptr& checkable, const
 /**
  * @threadsafety Always.
  */
-void CompatLogger::RemoveDowntimeHandler(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime)
+void CompatLogger::RemoveDowntimeHandler(const Downtime::Ptr& downtime)
 {
        Host::Ptr host;
        Service::Ptr service;
-       tie(host, service) = GetHostService(checkable);
+       tie(host, service) = GetHostService(downtime->GetCheckable());
 
        if (!downtime)
                return;
index 79d08acce06ddc23462e3935ffffca893bba3e2d..11801dac8b524e636703078d5ce2bac3c1d66d21 100644 (file)
@@ -44,7 +44,7 @@ public:
        virtual void ValidateRotationMethod(const String& value, const ValidationUtils& utils) override;
 
 protected:
-       virtual void Start(void) override;
+       virtual void Start(bool runtimeCreated) override;
 
 private:
        void WriteLine(const String& line);
@@ -56,8 +56,8 @@ private:
            const String& author, const String& comment_text, const String& command_name);
        void FlappingChangedHandler(const Checkable::Ptr& checkable);
        void EnableFlappingChangedHandler(const Checkable::Ptr& checkable);
-       void TriggerDowntimeHandler(const Checkable::Ptr& service, const Downtime::Ptr& downtime);
-       void RemoveDowntimeHandler(const Checkable::Ptr& service, const Downtime::Ptr& downtime);
+       void TriggerDowntimeHandler(const Downtime::Ptr& downtime);
+       void RemoveDowntimeHandler(const Downtime::Ptr& downtime);
        void ExternalCommandHandler(const String& command, const std::vector<String>& arguments);
        void EventCommandHandler(const Checkable::Ptr& service);
 
index eefe4649f3dda288a45be0c733e1f5414a48dea5..8785ba5249db52f63d2a0e80bc25fb180689370a 100644 (file)
@@ -46,9 +46,9 @@ void ExternalCommandListener::StatsFunc(const Dictionary::Ptr& status, const Arr
 /**
  * Starts the component.
  */
-void ExternalCommandListener::Start(void)
+void ExternalCommandListener::Start(bool runtimeCreated)
 {
-       ObjectImpl<ExternalCommandListener>::Start();
+       ObjectImpl<ExternalCommandListener>::Start(runtimeCreated);
 
 #ifndef _WIN32
        m_CommandThread = boost::thread(boost::bind(&ExternalCommandListener::CommandPipeThread, this, GetCommandPath()));
index 41fba96731ed2a66a24e97228a49eaddb95db989..7673b60f6446d5e07dc09c92558fe868c0db0e28 100644 (file)
@@ -42,7 +42,7 @@ public:
        static void StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata);
 
 protected:
-       virtual void Start(void) override;
+       virtual void Start(bool runtimeCreated) override;
 
 private:
 #ifndef _WIN32
index c0a21c03c929c623ce62fc5984a4e2bfd02d1df6..d37c61355ac92abf7d50871536cdd410983d231d 100644 (file)
@@ -70,9 +70,9 @@ void StatusDataWriter::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr
 /**
  * Starts the component.
  */
-void StatusDataWriter::Start(void)
+void StatusDataWriter::Start(bool runtimeCreated)
 {
-       ObjectImpl<StatusDataWriter>::Start();
+       ObjectImpl<StatusDataWriter>::Start(runtimeCreated);
 
        m_ObjectsCacheOutdated = true;
 
@@ -88,17 +88,11 @@ void StatusDataWriter::Start(void)
 
 void StatusDataWriter::DumpComments(std::ostream& fp, const Checkable::Ptr& checkable)
 {
-       Dictionary::Ptr comments = checkable->GetComments();
-
        Host::Ptr host;
        Service::Ptr service;
        tie(host, service) = GetHostService(checkable);
 
-       ObjectLock olock(comments);
-
-       BOOST_FOREACH(const Dictionary::Pair& kv, comments) {
-               Comment::Ptr comment = kv.second;
-
+       BOOST_FOREACH(const Comment::Ptr& comment, checkable->GetComments()) {
                if (comment->IsExpired())
                        continue;
 
@@ -160,17 +154,11 @@ void StatusDataWriter::DumpCommand(std::ostream& fp, const Command::Ptr& command
 
 void StatusDataWriter::DumpDowntimes(std::ostream& fp, const Checkable::Ptr& checkable)
 {
-       Dictionary::Ptr downtimes = checkable->GetDowntimes();
-
        Host::Ptr host;
        Service::Ptr service;
        tie(host, service) = GetHostService(checkable);
 
-       ObjectLock olock(downtimes);
-
-       BOOST_FOREACH(const Dictionary::Pair& kv, downtimes) {
-               Downtime::Ptr downtime = kv.second;
-
+       BOOST_FOREACH(const Downtime::Ptr& downtime, checkable->GetDowntimes()) {
                if (downtime->IsExpired())
                        continue;
 
@@ -180,7 +168,7 @@ void StatusDataWriter::DumpDowntimes(std::ostream& fp, const Checkable::Ptr& che
                else
                        fp << "hostdowntime {" "\n";
 
-               Downtime::Ptr triggeredByObj = Service::GetDowntimeByID(downtime->GetTriggeredBy());
+               Downtime::Ptr triggeredByObj = Downtime::GetByName(downtime->GetTriggeredBy());
                int triggeredByLegacy = 0;
                if (triggeredByObj)
                        triggeredByLegacy = triggeredByObj->GetLegacyId();
@@ -830,8 +818,8 @@ void StatusDataWriter::StatusTimerHandler(void)
                    "\t" "passive_host_check_stats=" << CIB::GetPassiveHostChecksStatistics(60) << "," << CIB::GetPassiveHostChecksStatistics(5 * 60) << "," << CIB::GetPassiveHostChecksStatistics(15 * 60) << "\n"
                    "\t" "active_scheduled_service_check_stats=" << CIB::GetActiveServiceChecksStatistics(60) << "," << CIB::GetActiveServiceChecksStatistics(5 * 60) << "," << CIB::GetActiveServiceChecksStatistics(15 * 60) << "\n"
                    "\t" "passive_service_check_stats=" << CIB::GetPassiveServiceChecksStatistics(60) << "," << CIB::GetPassiveServiceChecksStatistics(5 * 60) << "," << CIB::GetPassiveServiceChecksStatistics(15 * 60) << "\n"
-                   "\t" "next_downtime_id=" << Service::GetNextDowntimeID() << "\n"
-                   "\t" "next_comment_id=" << Service::GetNextCommentID() << "\n";
+                   "\t" "next_downtime_id=" << Downtime::GetNextDowntimeID() << "\n"
+                   "\t" "next_comment_id=" << Comment::GetNextCommentID() << "\n";
 
        statusfp << "\t" "}" "\n"
                    "\n";
index c6ee85a9ce8467fd53d08a28984a9baa8af57e40..b8df2f2b770ea212242f1d2e0cc55d912a3fe54e 100644 (file)
@@ -47,7 +47,7 @@ public:
        static void StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata);
 
 protected:
-       virtual void Start(void) override;
+       virtual void Start(bool runtimeCreated) override;
 
 private:
        Timer::Ptr m_StatusTimer;
index 91bfbf164e9ec42bfe0c9bc36b610cd6a64bee3b..535ae143a5997d849bd005d4889c52191f8c5009 100644 (file)
@@ -224,7 +224,19 @@ ConfigObject::Ptr ConfigItem::Commit(bool discard)
                dobj->SetShortName(item_name);
 
        dobj->SetName(name);
-       dobj->OnConfigLoaded();
+
+       try {
+               dobj->OnConfigLoaded();
+       } catch (const std::exception& ex) {
+               if (m_IgnoreOnError) {
+                       Log(LogWarning, "ConfigObject")
+                           << "Ignoring config object '" << m_Name << "' of type '" << m_Type << "' due to errors: " << DiagnosticInformation(ex);
+
+                       return ConfigObject::Ptr();
+               }
+
+               throw;
+       }
 
        {
                boost::mutex::scoped_lock lock(m_Mutex);
@@ -342,6 +354,24 @@ ConfigItem::Ptr ConfigItem::GetByTypeAndName(const String& type, const String& n
        return it2->second;
 }
 
+void ConfigItem::OnAllConfigLoadedWrapper(void)
+{
+       try {
+               m_Object->OnAllConfigLoaded();
+       } catch (const std::exception& ex) {
+               if (m_IgnoreOnError) {
+                       Log(LogWarning, "ConfigObject")
+                           << "Ignoring config object '" << m_Name << "' of type '" << m_Type << "' due to errors: " << DiagnosticInformation(ex);
+
+                       Unregister();
+
+                       return;
+               }
+
+               throw;
+       }
+}
+
 bool ConfigItem::CommitNewItems(WorkQueue& upq, std::vector<ConfigItem::Ptr>& newItems)
 {
        typedef std::pair<ConfigItem::Ptr, bool> ItemPair;
@@ -429,7 +459,7 @@ bool ConfigItem::CommitNewItems(WorkQueue& upq, std::vector<ConfigItem::Ptr>& ne
                                        continue;
 
                                if (item->m_Type == type)
-                                       upq.Enqueue(boost::bind(&ConfigObject::OnAllConfigLoaded, item->m_Object));
+                                       upq.Enqueue(boost::bind(&ConfigItem::OnAllConfigLoadedWrapper, item));
                        }
 
                        completed_types.insert(type);
@@ -498,8 +528,11 @@ bool ConfigItem::CommitItems(WorkQueue& upq)
        return true;
 }
 
-bool ConfigItem::ActivateItems(WorkQueue& upq, bool restoreState)
+bool ConfigItem::ActivateItems(WorkQueue& upq, bool restoreState, bool runtimeCreated)
 {
+       static boost::mutex mtx;
+       boost::mutex::scoped_lock lock(mtx);
+
        if (restoreState) {
                /* restore the previous program state */
                try {
@@ -521,7 +554,7 @@ bool ConfigItem::ActivateItems(WorkQueue& upq, bool restoreState)
                        Log(LogDebug, "ConfigItem")
                            << "Activating object '" << object->GetName() << "' of type '" << object->GetType()->GetName() << "'";
 #endif /* I2_DEBUG */
-                       upq.Enqueue(boost::bind(&ConfigObject::Activate, object));
+                       upq.Enqueue(boost::bind(&ConfigObject::Activate, object, runtimeCreated));
                }
        }
 
index 6439d428e493cdeca99e2755254f865333cffbd6..b53327e6209595f97a912b28e282626eaadac778 100644 (file)
@@ -68,7 +68,7 @@ public:
            const String& name);
 
        static bool CommitItems(WorkQueue& upq);
-       static bool ActivateItems(WorkQueue& upq, bool restoreState);
+       static bool ActivateItems(WorkQueue& upq, bool restoreState, bool runtimeCreated = false);
 
        static bool CommitAndActivate(void);
 
@@ -103,6 +103,8 @@ private:
            const String& name);
 
        static bool CommitNewItems(WorkQueue& upq, std::vector<ConfigItem::Ptr>& newItems);
+
+       void OnAllConfigLoadedWrapper(void);
 };
 
 }
index c78065505288d5abb3ed177742a4b18246bade92..1bbcf71d8605b7a167ab8a3c6523eb5d8cbba02a 100644 (file)
@@ -56,9 +56,9 @@ void DbConnection::OnConfigLoaded(void)
        boost::call_once(m_OnceFlag, InitializeDbTimer);
 }
 
-void DbConnection::Start(void)
+void DbConnection::Start(bool runtimeCreated)
 {
-       ObjectImpl<DbConnection>::Start();
+       ObjectImpl<DbConnection>::Start(runtimeCreated);
 
        DbObject::OnQuery.connect(boost::bind(&DbConnection::ExecuteQuery, this, _1));
        ConfigObject::OnActiveChanged.connect(boost::bind(&DbConnection::UpdateObject, this, _1));
index 43d215ae7206a4c17f8b9275a51fb53c16f5f0a9..58fe2594f1fc8bfcec859fc943e8baf6df86f194 100644 (file)
@@ -78,7 +78,7 @@ public:
 
 protected:
        virtual void OnConfigLoaded(void) override;
-       virtual void Start(void) override;
+       virtual void Start(bool runtimeCreated) override;
        virtual void Resume(void) override;
        virtual void Pause(void) override;
 
index 10fe515dce4dcf0c474750a4ce180f5151b37648..a0c5d58127788728d741264493082fcf710591da 100644 (file)
@@ -43,11 +43,11 @@ INITIALIZE_ONCE(&DbEvents::StaticInitialize);
 void DbEvents::StaticInitialize(void)
 {
        /* Status */
-       Checkable::OnCommentAdded.connect(boost::bind(&DbEvents::AddComment, _1, _2));
-       Checkable::OnCommentRemoved.connect(boost::bind(&DbEvents::RemoveComment, _1, _2));
-       Checkable::OnDowntimeAdded.connect(boost::bind(&DbEvents::AddDowntime, _1, _2, true));
-       Checkable::OnDowntimeRemoved.connect(boost::bind(&DbEvents::RemoveDowntime, _1, _2));
-       Checkable::OnDowntimeTriggered.connect(boost::bind(&DbEvents::TriggerDowntime, _1, _2));
+       Comment::OnCommentAdded.connect(boost::bind(&DbEvents::AddComment, _1));
+       Comment::OnCommentRemoved.connect(boost::bind(&DbEvents::RemoveComment, _1));
+       Downtime::OnDowntimeAdded.connect(boost::bind(&DbEvents::AddDowntime, _1, true));
+       Downtime::OnDowntimeRemoved.connect(boost::bind(&DbEvents::RemoveDowntime, _1));
+       Downtime::OnDowntimeTriggered.connect(boost::bind(&DbEvents::TriggerDowntime, _1));
        Checkable::OnAcknowledgementSet.connect(boost::bind(&DbEvents::AddAcknowledgement, _1, _4));
        Checkable::OnAcknowledgementCleared.connect(boost::bind(&DbEvents::RemoveAcknowledgement, _1));
 
@@ -64,8 +64,8 @@ void DbEvents::StaticInitialize(void)
        Checkable::OnReachabilityChanged.connect(boost::bind(&DbEvents::ReachabilityChangedHandler, _1, _2, _3));
 
        /* History */
-       Checkable::OnCommentAdded.connect(boost::bind(&DbEvents::AddCommentHistory, _1, _2));
-       Checkable::OnDowntimeAdded.connect(boost::bind(&DbEvents::AddDowntimeHistory, _1, _2));
+       Comment::OnCommentAdded.connect(boost::bind(&DbEvents::AddCommentHistory, _1));
+       Downtime::OnDowntimeAdded.connect(boost::bind(&DbEvents::AddDowntimeHistory, _1));
        Checkable::OnAcknowledgementSet.connect(boost::bind(&DbEvents::AddAcknowledgementHistory, _1, _2, _3, _4, _5, _6));
 
        Checkable::OnNotificationSentToAllUsers.connect(boost::bind(&DbEvents::AddNotificationHistory, _1, _2, _3, _4, _5, _6, _7));
@@ -76,8 +76,8 @@ void DbEvents::StaticInitialize(void)
        Checkable::OnNotificationSentToUser.connect(boost::bind(&DbEvents::AddNotificationSentLogHistory, _1, _2, _3, _4, _5, _6, _7));
        Checkable::OnFlappingChanged.connect(boost::bind(&DbEvents::AddFlappingChangedLogHistory, _1));
        Checkable::OnEnableFlappingChanged.connect(boost::bind(&DbEvents::AddEnableFlappingChangedLogHistory, _1));
-       Checkable::OnDowntimeTriggered.connect(boost::bind(&DbEvents::AddTriggerDowntimeLogHistory, _1, _2));
-       Checkable::OnDowntimeRemoved.connect(boost::bind(&DbEvents::AddRemoveDowntimeLogHistory, _1, _2));
+       Downtime::OnDowntimeTriggered.connect(boost::bind(&DbEvents::AddTriggerDowntimeLogHistory, _1));
+       Downtime::OnDowntimeRemoved.connect(boost::bind(&DbEvents::AddRemoveDowntimeLogHistory, _1));
 
        Checkable::OnFlappingChanged.connect(boost::bind(&DbEvents::AddFlappingChangedHistory, _1));
        Checkable::OnEnableFlappingChanged.connect(boost::bind(&DbEvents::AddEnableFlappingChangedHistory, _1));
@@ -303,45 +303,30 @@ void DbEvents::EnableChangedHandlerInternal(const Checkable::Ptr& checkable, con
 /* comments */
 void DbEvents::AddComments(const Checkable::Ptr& checkable)
 {
-       /* dump all comments */
-       Dictionary::Ptr comments = checkable->GetComments();
-
-       if (comments->GetLength() > 0)
-               RemoveComments(checkable);
-
-       ObjectLock olock(comments);
-
-       BOOST_FOREACH(const Dictionary::Pair& kv, comments) {
-               AddComment(checkable, kv.second);
+       BOOST_FOREACH(const Comment::Ptr& comment, checkable->GetComments()) {
+               AddComment(comment);
        }
 }
 
-void DbEvents::AddComment(const Checkable::Ptr& checkable, const Comment::Ptr& comment)
+void DbEvents::AddComment(const Comment::Ptr& comment)
 {
-       AddCommentInternal(checkable, comment, false);
+       AddCommentInternal(comment, false);
 }
 
-void DbEvents::AddCommentHistory(const Checkable::Ptr& checkable, const Comment::Ptr& comment)
+void DbEvents::AddCommentHistory(const Comment::Ptr& comment)
 {
-       AddCommentInternal(checkable, comment, true);
+       AddCommentInternal(comment, true);
 }
 
-void DbEvents::AddCommentInternal(const Checkable::Ptr& checkable, const Comment::Ptr& comment, bool historical)
+void DbEvents::AddCommentInternal(const Comment::Ptr& comment, bool historical)
 {
-       if (!comment) {
-               Log(LogWarning, "DbEvents", "comment does not exist. not adding it.");
-               return;
-       }
-
-       Log(LogDebug, "DbEvents")
-           << "adding service comment (id = " << comment->GetLegacyId() << ") for '" << checkable->GetName() << "'";
-
-       /* add the service comment */
-       AddCommentByType(checkable, comment, historical);
+       AddCommentByType(comment, historical);
 }
 
-void DbEvents::AddCommentByType(const ConfigObject::Ptr& object, const Comment::Ptr& comment, bool historical)
+void DbEvents::AddCommentByType(const Comment::Ptr& comment, bool historical)
 {
+       Checkable::Ptr checkable = comment->GetCheckable();
+
        unsigned long entry_time = static_cast<long>(comment->GetEntryTime());
        unsigned long entry_time_usec = (comment->GetEntryTime() - entry_time) * 1000 * 1000;
 
@@ -349,13 +334,13 @@ void DbEvents::AddCommentByType(const ConfigObject::Ptr& object, const Comment::
        fields1->Set("entry_time", DbValue::FromTimestamp(entry_time));
        fields1->Set("entry_time_usec", entry_time_usec);
        fields1->Set("entry_type", comment->GetEntryType());
-       fields1->Set("object_id", object);
+       fields1->Set("object_id", checkable);
 
-       if (object->GetType() == ConfigType::GetByName("Host")) {
+       if (checkable->GetType() == ConfigType::GetByName("Host")) {
                fields1->Set("comment_type", 2);
                /* requires idoutils 1.10 schema fix */
                fields1->Set("internal_comment_id", comment->GetLegacyId());
-       } else if (object->GetType() == ConfigType::GetByName("Service")) {
+       } else if (checkable->GetType() == ConfigType::GetByName("Service")) {
                fields1->Set("comment_type", 1);
                fields1->Set("internal_comment_id", comment->GetLegacyId());
        } else {
@@ -404,15 +389,9 @@ void DbEvents::RemoveComments(const Checkable::Ptr& checkable)
        DbObject::OnQuery(query1);
 }
 
-void DbEvents::RemoveComment(const Checkable::Ptr& checkable, const Comment::Ptr& comment)
+void DbEvents::RemoveComment(const Comment::Ptr& comment)
 {
-       if (!comment) {
-               Log(LogWarning, "DbEvents", "comment does not exist. not deleting it.");
-               return;
-       }
-
-       Log(LogDebug, "DbEvents")
-           << "removing service comment (id = " << comment->GetLegacyId() << ") for '" << checkable->GetName() << "'";
+       Checkable::Ptr checkable = comment->GetCheckable();
 
        /* Status */
        DbQuery query1;
@@ -451,51 +430,39 @@ void DbEvents::RemoveComment(const Checkable::Ptr& checkable, const Comment::Ptr
 /* downtimes */
 void DbEvents::AddDowntimes(const Checkable::Ptr& checkable)
 {
-       /* dump all downtimes */
-       Dictionary::Ptr downtimes = checkable->GetDowntimes();
-
-       if (downtimes->GetLength() > 0)
-               RemoveDowntimes(checkable);
+       RemoveDowntimes(checkable);
 
-       ObjectLock olock(downtimes);
-
-       BOOST_FOREACH(const Dictionary::Pair& kv, downtimes) {
-               AddDowntime(checkable, kv.second, false);
+       BOOST_FOREACH(const Downtime::Ptr& downtime, checkable->GetDowntimes()) {
+               AddDowntime(downtime, false);
        }
 }
 
-void DbEvents::AddDowntime(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime, bool remove_existing)
+void DbEvents::AddDowntime(const Downtime::Ptr& downtime, bool remove_existing)
 {
        /*
         * make sure to delete any old downtime to avoid multiple inserts from
         * configured ScheduledDowntime dumps and CreateNextDowntime() calls
         */
        if (remove_existing)
-               RemoveDowntime(checkable, downtime);
-       AddDowntimeInternal(checkable, downtime, false);
+               RemoveDowntime(downtime);
+
+       AddDowntimeInternal(downtime, false);
 }
 
-void DbEvents::AddDowntimeHistory(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime)
+void DbEvents::AddDowntimeHistory(const Downtime::Ptr& downtime)
 {
-       AddDowntimeInternal(checkable, downtime, true);
+       AddDowntimeInternal(downtime, true);
 }
 
-void DbEvents::AddDowntimeInternal(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime, bool historical)
+void DbEvents::AddDowntimeInternal(const Downtime::Ptr& downtime, bool historical)
 {
-       if (!downtime) {
-               Log(LogWarning, "DbEvents", "downtime does not exist. not adding it.");
-               return;
-       }
-
-       Log(LogDebug, "DbEvents")
-           << "adding service downtime (id = " << downtime->GetLegacyId() << ") for '" << checkable->GetName() << "'";
-
-       /* add the downtime */
-       AddDowntimeByType(checkable, downtime, historical);
+       AddDowntimeByType(downtime, historical);
 }
 
-void DbEvents::AddDowntimeByType(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime, bool historical)
+void DbEvents::AddDowntimeByType(const Downtime::Ptr& downtime, bool historical)
 {
+       Checkable::Ptr checkable = downtime->GetCheckable();
+
        Dictionary::Ptr fields1 = new Dictionary();
        fields1->Set("entry_time", DbValue::FromTimestamp(downtime->GetEntryTime()));
        fields1->Set("object_id", checkable);
@@ -514,7 +481,7 @@ void DbEvents::AddDowntimeByType(const Checkable::Ptr& checkable, const Downtime
 
        fields1->Set("author_name", downtime->GetAuthor());
        fields1->Set("comment_data", downtime->GetComment());
-       fields1->Set("triggered_by_id", Service::GetDowntimeByID(downtime->GetTriggeredBy()));
+       fields1->Set("triggered_by_id", Downtime::GetByName(downtime->GetTriggeredBy()));
        fields1->Set("is_fixed", downtime->GetFixed() ? 1 : 0);
        fields1->Set("duration", downtime->GetDuration());
        fields1->Set("scheduled_start_time", DbValue::FromTimestamp(downtime->GetStartTime()));
@@ -544,9 +511,6 @@ void DbEvents::AddDowntimeByType(const Checkable::Ptr& checkable, const Downtime
 
 void DbEvents::RemoveDowntimes(const Checkable::Ptr& checkable)
 {
-       Log(LogDebug, "DbEvents")
-           << "removing service downtimes for '" << checkable->GetName() << "'";
-
        DbQuery query1;
        query1.Table = "scheduleddowntime";
        query1.Type = DbQueryDelete;
@@ -556,15 +520,9 @@ void DbEvents::RemoveDowntimes(const Checkable::Ptr& checkable)
        DbObject::OnQuery(query1);
 }
 
-void DbEvents::RemoveDowntime(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime)
+void DbEvents::RemoveDowntime(const Downtime::Ptr& downtime)
 {
-       if (!downtime) {
-               Log(LogWarning, "DbEvents", "downtime does not exist. not adding it.");
-               return;
-       }
-
-       Log(LogDebug, "DbEvents")
-           << "removing service downtime (id = " << downtime->GetLegacyId() << ") for '" << checkable->GetName() << "'";
+       Checkable::Ptr checkable = downtime->GetCheckable();
 
        /* Status */
        DbQuery query1;
@@ -632,15 +590,9 @@ void DbEvents::RemoveDowntime(const Checkable::Ptr& checkable, const Downtime::P
        DbObject::OnQuery(query4);
 }
 
-void DbEvents::TriggerDowntime(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime)
+void DbEvents::TriggerDowntime(const Downtime::Ptr& downtime)
 {
-       if (!downtime) {
-               Log(LogWarning, "DbEvents", "downtime does not exist. not updating it.");
-               return;
-       }
-
-       Log(LogDebug, "DbEvents")
-           << "updating triggered service downtime (id = " << downtime->GetLegacyId() << ") for '" << checkable->GetName() << "'";
+       Checkable::Ptr checkable = downtime->GetCheckable();
 
        double now = Utility::GetTime();
        std::pair<unsigned long, unsigned long> time_bag = CompatUtility::ConvertTimestamp(now);
@@ -1036,10 +988,9 @@ void DbEvents::AddCheckResultLogHistory(const Checkable::Ptr& checkable, const C
        AddLogHistory(checkable, msgbuf.str(), type);
 }
 
-void DbEvents::AddTriggerDowntimeLogHistory(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime)
+void DbEvents::AddTriggerDowntimeLogHistory(const Downtime::Ptr& downtime)
 {
-       if (!downtime)
-               return;
+       Checkable::Ptr checkable = downtime->GetCheckable();
 
        Host::Ptr host;
        Service::Ptr service;
@@ -1065,10 +1016,9 @@ void DbEvents::AddTriggerDowntimeLogHistory(const Checkable::Ptr& checkable, con
        AddLogHistory(checkable, msgbuf.str(), LogEntryTypeInfoMessage);
 }
 
-void DbEvents::AddRemoveDowntimeLogHistory(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime)
+void DbEvents::AddRemoveDowntimeLogHistory(const Downtime::Ptr& downtime)
 {
-       if (!downtime)
-               return;
+       Checkable::Ptr checkable = downtime->GetCheckable();
 
        String downtime_output;
        String downtime_state_str;
index c1c3b7b7dde80cfa3160e922b922f6949a0763b1..1acaaf60e40a04ba01c2113ef918dc9c6d088cfd 100644 (file)
@@ -61,11 +61,11 @@ class DbEvents
 public:
        static void StaticInitialize(void);
 
-       static void AddCommentByType(const ConfigObject::Ptr& object, const Comment::Ptr& comment, bool historical);
+       static void AddCommentByType(const Comment::Ptr& comment, bool historical);
        static void AddComments(const Checkable::Ptr& checkable);
        static void RemoveComments(const Checkable::Ptr& checkable);
 
-       static void AddDowntimeByType(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime, bool historical);
+       static void AddDowntimeByType(const Downtime::Ptr& downtime, bool historical);
        static void AddDowntimes(const Checkable::Ptr& checkable);
        static void RemoveDowntimes(const Checkable::Ptr& checkable);
 
@@ -82,12 +82,12 @@ public:
        static void EnablePerfdataChangedHandler(const Checkable::Ptr& checkable);
        static void EnableFlappingChangedHandler(const Checkable::Ptr& checkable);
 
-       static void AddComment(const Checkable::Ptr& checkable, const Comment::Ptr& comment);
-       static void RemoveComment(const Checkable::Ptr& checkable, const Comment::Ptr& comment);
+       static void AddComment(const Comment::Ptr& comment);
+       static void RemoveComment(const Comment::Ptr& comment);
 
-       static void AddDowntime(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime, bool remove_existing);
-       static void RemoveDowntime(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime);
-       static void TriggerDowntime(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime);
+       static void AddDowntime(const Downtime::Ptr& downtime, bool remove_existing);
+       static void RemoveDowntime(const Downtime::Ptr& downtime);
+       static void TriggerDowntime(const Downtime::Ptr& downtime);
 
        static void AddAcknowledgement(const Checkable::Ptr& checkable, AcknowledgementType type);
        static void RemoveAcknowledgement(const Checkable::Ptr& checkable);
@@ -96,8 +96,8 @@ public:
        static void ReachabilityChangedHandler(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, std::set<Checkable::Ptr> children);
 
        /* comment, downtime, acknowledgement history */
-       static void AddCommentHistory(const Checkable::Ptr& checkable, const Comment::Ptr& comment);
-       static void AddDowntimeHistory(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime);
+       static void AddCommentHistory(const Comment::Ptr& comment);
+       static void AddDowntimeHistory(const Downtime::Ptr& downtime);
        static void AddAcknowledgementHistory(const Checkable::Ptr& checkable, const String& author, const String& comment,
            AcknowledgementType type, bool notify, double expiry);
 
@@ -111,8 +111,8 @@ public:
 
        /* logentries */
        static void AddCheckResultLogHistory(const Checkable::Ptr& checkable, const CheckResult::Ptr &cr);
-       static void AddTriggerDowntimeLogHistory(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime);
-       static void AddRemoveDowntimeLogHistory(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime);
+       static void AddTriggerDowntimeLogHistory(const Downtime::Ptr& downtime);
+       static void AddRemoveDowntimeLogHistory(const Downtime::Ptr& downtime);
        static void AddNotificationSentLogHistory(const Notification::Ptr& notification, const Checkable::Ptr& checkable,
            const User::Ptr& user, NotificationType notification_type, const CheckResult::Ptr& cr, const String& author,
            const String& comment_text);
@@ -130,8 +130,8 @@ public:
 private:
        DbEvents(void);
 
-       static void AddCommentInternal(const Checkable::Ptr& checkable, const Comment::Ptr& comment, bool historical);
-       static void AddDowntimeInternal(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime, bool historical);
+       static void AddCommentInternal(const Comment::Ptr& comment, bool historical);
+       static void AddDowntimeInternal(const Downtime::Ptr& downtime, bool historical);
        static void EnableChangedHandlerInternal(const Checkable::Ptr& checkable, const String& fieldName, bool enabled);
 };
 
index f837546c2db145b498d68297257df2f827bce1ec..0605a44e1433fce3c960d4c80c1bed46987b657e 100644 (file)
@@ -33,9 +33,9 @@ REGISTER_APIFUNCTION(HelloWorld, demo, &Demo::DemoMessageHandler);
 /**
  * Starts the component.
  */
-void Demo::Start(void)
+void Demo::Start(bool runtimeCreated)
 {
-       ObjectImpl<Demo>::Start();
+       ObjectImpl<Demo>::Start(runtimeCreated);
 
        m_DemoTimer = new Timer();
        m_DemoTimer->SetInterval(5);
index c749270196fb06e446d08e21cb04d28e664e4bf9..259c84dcafccdb4fd0c2918d538236345c7ec591 100644 (file)
@@ -36,7 +36,7 @@ public:
        DECLARE_OBJECT(Demo);
        DECLARE_OBJECTNAME(Demo);
 
-       virtual void Start(void);
+       virtual void Start(bool runtimeCreated);
 
        static Value DemoMessageHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params);
 
index 1dc0c0bc0883f2d620b04d441461dc5305a96ac4..6c6e8495d4774e69656e08b1d6565de3285c5823 100644 (file)
@@ -215,7 +215,7 @@ Dictionary::Ptr ApiActions::AcknowledgeProblem(const ConfigObject::Ptr& object,
                        return ApiActions::CreateResult(409, "Service " + checkable->GetName() + " is OK.");
        }
 
-       checkable->AddComment(CommentAcknowledgement, HttpUtility::GetLastParameter(params, "author"),
+       Comment::AddComment(checkable, CommentAcknowledgement, HttpUtility::GetLastParameter(params, "author"),
            HttpUtility::GetLastParameter(params, "comment"), timestamp);
        checkable->AcknowledgeProblem(HttpUtility::GetLastParameter(params, "author"),
            HttpUtility::GetLastParameter(params, "comment"), sticky, notify, timestamp);
@@ -250,11 +250,11 @@ Dictionary::Ptr ApiActions::AddComment(const ConfigObject::Ptr& object,
        if (!params->Contains("author") || !params->Contains("comment"))
                return ApiActions::CreateResult(403, "Comments require author and comment.");
 
-       String comment_id = checkable->AddComment(CommentUser,
+       String comment_id = Comment::AddComment(checkable, CommentUser,
            HttpUtility::GetLastParameter(params, "author"),
            HttpUtility::GetLastParameter(params, "comment"), 0);
 
-       Comment::Ptr comment = Checkable::GetCommentByID(comment_id);
+       Comment::Ptr comment = Comment::GetByName(comment_id);
        int legacy_id = comment->GetLegacyId();
 
        Dictionary::Ptr additional = new Dictionary();
@@ -287,7 +287,7 @@ Dictionary::Ptr ApiActions::RemoveCommentByID(const ConfigObject::Ptr& object,
 
        String comment_id = HttpUtility::GetLastParameter(params, "comment_id");
 
-       Service::RemoveComment(comment_id);
+       Comment::RemoveComment(comment_id);
 
        return ApiActions::CreateResult(200, "Successfully removed comment '" + comment_id + "'.");
 }
@@ -311,21 +311,15 @@ Dictionary::Ptr ApiActions::ScheduleDowntime(const ConfigObject::Ptr& object,
        if (params->Contains("fixed"))
                fixed = HttpUtility::GetLastParameter(params, "fixed");
 
-       int triggeredByLegacy = 0;
-
-       if (params->Contains("trigger_id"))
-               triggeredByLegacy = HttpUtility::GetLastParameter(params, "trigger_id");
-
-       String triggeredBy;
-       if (triggeredByLegacy)
-               triggeredBy = Service::GetDowntimeIDFromLegacyID(triggeredByLegacy);
-
-       String downtime_id = checkable->AddDowntime(HttpUtility::GetLastParameter(params, "author"),
-           HttpUtility::GetLastParameter(params, "comment"), HttpUtility::GetLastParameter(params, "start_time"),
-           HttpUtility::GetLastParameter(params, "end_time"), fixed, triggeredBy,
+       String downtime_id = Downtime::AddDowntime(checkable,
+           HttpUtility::GetLastParameter(params, "author"),
+           HttpUtility::GetLastParameter(params, "comment"),
+           HttpUtility::GetLastParameter(params, "start_time"),
+           HttpUtility::GetLastParameter(params, "end_time"), fixed,
+           HttpUtility::GetLastParameter(params, "trigger_id"),
            HttpUtility::GetLastParameter(params, "duration"));
 
-       Downtime::Ptr downtime = Checkable::GetDowntimeByID(downtime_id);
+       Downtime::Ptr downtime = Downtime::GetByName(downtime_id);
        int legacy_id = downtime->GetLegacyId();
 
        Dictionary::Ptr additional = new Dictionary();
@@ -357,7 +351,7 @@ Dictionary::Ptr ApiActions::RemoveDowntimeByID(const ConfigObject::Ptr& object,
 
        String downtime_id = HttpUtility::GetLastParameter(params, "downtime_id");
 
-       Service::RemoveDowntime(downtime_id, true);
+       Downtime::RemoveDowntime(downtime_id, true);
 
        return ApiActions::CreateResult(200, "Successfully removed downtime '" + downtime_id + "'.");
 }
index 121c9dd4eda500d05cfd049c27dd21e6b7702ab1..80ea790b686ea30369caebf3e235d88da024fa3a 100644 (file)
@@ -39,12 +39,12 @@ void ApiEvents::StaticInitialize(void)
        Checkable::OnAcknowledgementSet.connect(&ApiEvents::AcknowledgementSetHandler);
        Checkable::OnAcknowledgementCleared.connect(&ApiEvents::AcknowledgementClearedHandler);
 
-       Checkable::OnCommentAdded.connect(&ApiEvents::CommentAddedHandler);
-       Checkable::OnCommentRemoved.connect(&ApiEvents::CommentRemovedHandler);
+       Comment::OnCommentAdded.connect(&ApiEvents::CommentAddedHandler);
+       Comment::OnCommentRemoved.connect(&ApiEvents::CommentRemovedHandler);
 
-       Checkable::OnDowntimeAdded.connect(&ApiEvents::DowntimeAddedHandler);
-       Checkable::OnDowntimeRemoved.connect(&ApiEvents::DowntimeRemovedHandler);
-       Checkable::OnDowntimeTriggered.connect(&ApiEvents::DowntimeTriggeredHandler);
+       Downtime::OnDowntimeAdded.connect(&ApiEvents::DowntimeAddedHandler);
+       Downtime::OnDowntimeRemoved.connect(&ApiEvents::DowntimeRemovedHandler);
+       Downtime::OnDowntimeTriggered.connect(&ApiEvents::DowntimeTriggeredHandler);
 }
 
 void ApiEvents::CheckResultHandler(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, const MessageOrigin::Ptr& origin)
@@ -243,7 +243,7 @@ void ApiEvents::AcknowledgementClearedHandler(const Checkable::Ptr& checkable, c
        result->Set("acknowledgement_type", AcknowledgementNone);
 }
 
-void ApiEvents::CommentAddedHandler(const Checkable::Ptr& checkable, const Comment::Ptr& comment, const MessageOrigin::Ptr& origin)
+void ApiEvents::CommentAddedHandler(const Comment::Ptr& comment)
 {
        std::vector<EventQueue::Ptr> queues = EventQueue::GetQueuesForType("CommentAdded");
 
@@ -256,22 +256,14 @@ void ApiEvents::CommentAddedHandler(const Checkable::Ptr& checkable, const Comme
        result->Set("type", "CommentAdded");
        result->Set("timestamp", Utility::GetTime());
 
-       Host::Ptr host;
-       Service::Ptr service;
-       tie(host, service) = GetHostService(checkable);
-
-       result->Set("host", host->GetName());
-       if (service)
-               result->Set("service", service->GetShortName());
-
-       result->Set("comment", Serialize(comment));
+       result->Set("comment", Serialize(comment, FAConfig | FAState));
 
        BOOST_FOREACH(const EventQueue::Ptr& queue, queues) {
                queue->ProcessEvent(result);
        }
 }
 
-void ApiEvents::CommentRemovedHandler(const Checkable::Ptr& checkable, const Comment::Ptr& comment, const MessageOrigin::Ptr& origin)
+void ApiEvents::CommentRemovedHandler(const Comment::Ptr& comment)
 {
        std::vector<EventQueue::Ptr> queues = EventQueue::GetQueuesForType("CommentRemoved");
 
@@ -284,20 +276,14 @@ void ApiEvents::CommentRemovedHandler(const Checkable::Ptr& checkable, const Com
        result->Set("type", "CommentRemoved");
        result->Set("timestamp", Utility::GetTime());
 
-       Host::Ptr host;
-       Service::Ptr service;
-       tie(host, service) = GetHostService(checkable);
-
-       result->Set("host", host->GetName());
-       if (service)
-               result->Set("service", service->GetShortName());
+       result->Set("comment", Serialize(comment, FAConfig | FAState));
 
        BOOST_FOREACH(const EventQueue::Ptr& queue, queues) {
                queue->ProcessEvent(result);
        }
 }
 
-void ApiEvents::DowntimeAddedHandler(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime, const MessageOrigin::Ptr& origin)
+void ApiEvents::DowntimeAddedHandler(const Downtime::Ptr& downtime)
 {
        std::vector<EventQueue::Ptr> queues = EventQueue::GetQueuesForType("DowntimeAdded");
 
@@ -310,22 +296,14 @@ void ApiEvents::DowntimeAddedHandler(const Checkable::Ptr& checkable, const Down
        result->Set("type", "DowntimeAdded");
        result->Set("timestamp", Utility::GetTime());
 
-       Host::Ptr host;
-       Service::Ptr service;
-       tie(host, service) = GetHostService(checkable);
-
-       result->Set("host", host->GetName());
-       if (service)
-               result->Set("service", service->GetShortName());
-
-       result->Set("downtime", Serialize(downtime));
+       result->Set("downtime", Serialize(downtime, FAConfig | FAState));
 
        BOOST_FOREACH(const EventQueue::Ptr& queue, queues) {
                queue->ProcessEvent(result);
        }
 }
 
-void ApiEvents::DowntimeRemovedHandler(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime, const MessageOrigin::Ptr& origin)
+void ApiEvents::DowntimeRemovedHandler(const Downtime::Ptr& downtime)
 {
        std::vector<EventQueue::Ptr> queues = EventQueue::GetQueuesForType("DowntimeRemoved");
 
@@ -338,20 +316,14 @@ void ApiEvents::DowntimeRemovedHandler(const Checkable::Ptr& checkable, const Do
        result->Set("type", "DowntimeRemoved");
        result->Set("timestamp", Utility::GetTime());
 
-       Host::Ptr host;
-       Service::Ptr service;
-       tie(host, service) = GetHostService(checkable);
-
-       result->Set("host", host->GetName());
-       if (service)
-               result->Set("service", service->GetShortName());
+       result->Set("downtime", Serialize(downtime, FAConfig | FAState));
 
        BOOST_FOREACH(const EventQueue::Ptr& queue, queues) {
                queue->ProcessEvent(result);
        }
 }
 
-void ApiEvents::DowntimeTriggeredHandler(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime)
+void ApiEvents::DowntimeTriggeredHandler(const Downtime::Ptr& downtime)
 {
        std::vector<EventQueue::Ptr> queues = EventQueue::GetQueuesForType("DowntimeTriggered");
 
@@ -364,14 +336,6 @@ void ApiEvents::DowntimeTriggeredHandler(const Checkable::Ptr& checkable, const
        result->Set("type", "DowntimeTriggered");
        result->Set("timestamp", Utility::GetTime());
 
-       Host::Ptr host;
-       Service::Ptr service;
-       tie(host, service) = GetHostService(checkable);
-
-       result->Set("host", host->GetName());
-       if (service)
-               result->Set("service", service->GetShortName());
-
        result->Set("downtime", Serialize(downtime));
 
        BOOST_FOREACH(const EventQueue::Ptr& queue, queues) {
index 9e889ffed29355035529a71bc11bb1525b426257..e3fc31ba0a7108d321ff357b02da1d96f0b05d8e 100644 (file)
@@ -49,12 +49,12 @@ public:
            bool notify, double expiry, const MessageOrigin::Ptr& origin);
        static void AcknowledgementClearedHandler(const Checkable::Ptr& checkable, const MessageOrigin::Ptr& origin);
 
-       static void CommentAddedHandler(const Checkable::Ptr& checkable, const Comment::Ptr& comment, const MessageOrigin::Ptr& origin);
-       static void CommentRemovedHandler(const Checkable::Ptr& checkable, const Comment::Ptr& comment, const MessageOrigin::Ptr& origin);
+       static void CommentAddedHandler(const Comment::Ptr& comment);
+       static void CommentRemovedHandler(const Comment::Ptr& comment);
 
-       static void DowntimeAddedHandler(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime, const MessageOrigin::Ptr& origin);
-       static void DowntimeRemovedHandler(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime, const MessageOrigin::Ptr& origin);
-       static void DowntimeTriggeredHandler(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime);
+       static void DowntimeAddedHandler(const Downtime::Ptr& downtime);
+       static void DowntimeRemovedHandler(const Downtime::Ptr& downtime);
+       static void DowntimeTriggeredHandler(const Downtime::Ptr& downtime);
 };
 
 }
index 89ea47611f05aa8a4eb09d35912b11be692de4bb..25f0038fd1d62f444c7d16edbebafa36c6e83c6b 100644 (file)
@@ -18,6 +18,7 @@
  ******************************************************************************/
 
 #include "icinga/service.hpp"
+#include "remote/configobjectutility.hpp"
 #include "base/configtype.hpp"
 #include "base/objectlock.hpp"
 #include "base/timer.hpp"
 
 using namespace icinga;
 
-static int l_NextCommentID = 1;
-static boost::mutex l_CommentMutex;
-static std::map<int, String> l_LegacyCommentsCache;
-static std::map<String, Checkable::Ptr> l_CommentsCache;
-static Timer::Ptr l_CommentsExpireTimer;
-
-boost::signals2::signal<void (const Checkable::Ptr&, const Comment::Ptr&, const MessageOrigin::Ptr&)> Checkable::OnCommentAdded;
-boost::signals2::signal<void (const Checkable::Ptr&, const Comment::Ptr&, const MessageOrigin::Ptr&)> Checkable::OnCommentRemoved;
-
-int Checkable::GetNextCommentID(void)
-{
-       boost::mutex::scoped_lock lock(l_CommentMutex);
-
-       return l_NextCommentID;
-}
-
-String Checkable::AddComment(CommentType entryType, const String& author,
-    const String& text, double expireTime, const String& id, const MessageOrigin::Ptr& origin)
-{
-       String uid;
-
-       if (id.IsEmpty())
-               uid = Utility::NewUniqueID();
-       else
-               uid = id;
-
-       Comment::Ptr comment = new Comment();
-       comment->SetId(uid);;
-       comment->SetEntryTime(Utility::GetTime());
-       comment->SetEntryType(entryType);
-       comment->SetAuthor(author);
-       comment->SetText(text);
-       comment->SetExpireTime(expireTime);
-
-       int legacy_id;
-
-       {
-               boost::mutex::scoped_lock lock(l_CommentMutex);
-               legacy_id = l_NextCommentID++;
-       }
-
-       comment->SetLegacyId(legacy_id);
-
-       GetComments()->Set(uid, comment);
-
-       {
-               boost::mutex::scoped_lock lock(l_CommentMutex);
-               l_LegacyCommentsCache[legacy_id] = uid;
-               l_CommentsCache[uid] = this;
-       }
-
-       OnCommentAdded(this, comment, origin);
-
-       return uid;
-}
 
 void Checkable::RemoveAllComments(void)
 {
-       std::vector<String> ids;
-       Dictionary::Ptr comments = GetComments();
-
-       {
-               ObjectLock olock(comments);
-               BOOST_FOREACH(const Dictionary::Pair& kv, comments) {
-                       ids.push_back(kv.first);
-               }
+       BOOST_FOREACH(const Comment::Ptr& comment, GetComments()) {
+               Comment::RemoveComment(comment->GetName());
        }
-
-       BOOST_FOREACH(const String& id, ids) {
-               RemoveComment(id);
-       }
-}
-
-void Checkable::RemoveComment(const String& id, const MessageOrigin::Ptr& origin)
-{
-       Checkable::Ptr owner = GetOwnerByCommentID(id);
-
-       if (!owner)
-               return;
-
-       Dictionary::Ptr comments = owner->GetComments();
-
-       ObjectLock olock(owner);
-
-       Comment::Ptr comment = comments->Get(id);
-
-       if (!comment)
-               return;
-
-       int legacy_id = comment->GetLegacyId();
-
-       comments->Remove(id);
-
-       {
-               boost::mutex::scoped_lock lock(l_CommentMutex);
-               l_LegacyCommentsCache.erase(legacy_id);
-               l_CommentsCache.erase(id);
-       }
-
-       OnCommentRemoved(owner, comment, origin);
-}
-
-String Checkable::GetCommentIDFromLegacyID(int id)
-{
-       boost::mutex::scoped_lock lock(l_CommentMutex);
-
-       std::map<int, String>::iterator it = l_LegacyCommentsCache.find(id);
-
-       if (it == l_LegacyCommentsCache.end())
-               return Empty;
-
-       return it->second;
-}
-
-Checkable::Ptr Checkable::GetOwnerByCommentID(const String& id)
-{
-       boost::mutex::scoped_lock lock(l_CommentMutex);
-
-       return l_CommentsCache[id];
-}
-
-Comment::Ptr Checkable::GetCommentByID(const String& id)
-{
-       Checkable::Ptr owner = GetOwnerByCommentID(id);
-
-       if (!owner)
-               return Comment::Ptr();
-
-       Dictionary::Ptr comments = owner->GetComments();
-
-       if (comments)
-               return comments->Get(id);
-
-       return Comment::Ptr();
 }
 
-void Checkable::AddCommentsToCache(void)
+void Checkable::RemoveCommentsByType(int type)
 {
-#ifdef I2_DEBUG
-       Log(LogDebug, "Checkable", "Updating Checkable comments cache.");
-#endif /* I2_DEBUG */
-
-       Dictionary::Ptr comments = GetComments();
-
-       ObjectLock olock(comments);
-
-       boost::mutex::scoped_lock lock(l_CommentMutex);
-
-       BOOST_FOREACH(const Dictionary::Pair& kv, comments) {
-               Comment::Ptr comment = kv.second;
-
-               int legacy_id = comment->GetLegacyId();
-
-               if (legacy_id >= l_NextCommentID)
-                       l_NextCommentID = legacy_id + 1;
-
-               l_LegacyCommentsCache[legacy_id] = kv.first;
-               l_CommentsCache[kv.first] = this;
+       BOOST_FOREACH(const Comment::Ptr& comment, GetComments()) {
+               if (comment->GetEntryType() == type)
+                       Comment::RemoveComment(comment->GetName());
        }
 }
 
-void Checkable::RemoveCommentsByType(int type)
+std::set<Comment::Ptr> Checkable::GetComments(void) const
 {
-       Dictionary::Ptr comments = GetComments();
-
-       std::vector<String> removedComments;
-
-       {
-               ObjectLock olock(comments);
-
-               BOOST_FOREACH(const Dictionary::Pair& kv, comments) {
-                       Comment::Ptr comment = kv.second;
-
-                       if (comment->GetEntryType() == type)
-                               removedComments.push_back(kv.first);
-               }
-       }
-
-       BOOST_FOREACH(const String& id, removedComments) {
-               RemoveComment(id);
-       }
+       boost::mutex::scoped_lock lock(m_CommentMutex);
+       return m_Comments;
 }
 
-void Checkable::RemoveExpiredComments(void)
+void Checkable::RegisterComment(const Comment::Ptr& comment)
 {
-       Dictionary::Ptr comments = GetComments();
-
-       std::vector<String> expiredComments;
-
-       {
-               ObjectLock olock(comments);
-
-               BOOST_FOREACH(const Dictionary::Pair& kv, comments) {
-                       Comment::Ptr comment = kv.second;
-
-                       if (comment->IsExpired())
-                               expiredComments.push_back(kv.first);
-               }
-       }
-
-       BOOST_FOREACH(const String& id, expiredComments) {
-               RemoveComment(id);
-       }
+       boost::mutex::scoped_lock lock(m_CommentMutex);
+       m_Comments.insert(comment);
 }
 
-void Checkable::CommentsExpireTimerHandler(void)
+void Checkable::UnregisterComment(const Comment::Ptr& comment)
 {
-       BOOST_FOREACH(const Host::Ptr& host, ConfigType::GetObjectsByType<Host>()) {
-               host->RemoveExpiredComments();
-       }
-
-       BOOST_FOREACH(const Service::Ptr& service, ConfigType::GetObjectsByType<Service>()) {
-               service->RemoveExpiredComments();
-       }
+       boost::mutex::scoped_lock lock(m_CommentMutex);
+       m_Comments.erase(comment);
 }
index a56d71de9249d9e4f409b51114870f28da3bef15..e41b7a08d8733b7807d75ae8a65be78350de2c7f 100644 (file)
 #include "base/configtype.hpp"
 #include "base/objectlock.hpp"
 #include "base/logger.hpp"
-#include "base/timer.hpp"
 #include "base/utility.hpp"
 #include "base/convert.hpp"
 #include <boost/foreach.hpp>
 
 using namespace icinga;
 
-static int l_NextDowntimeID = 1;
-static boost::mutex l_DowntimeMutex;
-static std::map<int, String> l_LegacyDowntimesCache;
-static std::map<String, Checkable::Ptr> l_DowntimesCache;
-static Timer::Ptr l_DowntimesExpireTimer;
-
-boost::signals2::signal<void (const Checkable::Ptr&, const Downtime::Ptr&, const MessageOrigin::Ptr&)> Checkable::OnDowntimeAdded;
-boost::signals2::signal<void (const Checkable::Ptr&, const Downtime::Ptr&, const MessageOrigin::Ptr&)> Checkable::OnDowntimeRemoved;
-boost::signals2::signal<void (const Checkable::Ptr&, const Downtime::Ptr&)> Checkable::OnDowntimeTriggered;
-
-INITIALIZE_ONCE(&Checkable::StartDowntimesExpiredTimer);
-
-int Checkable::GetNextDowntimeID(void)
-{
-       boost::mutex::scoped_lock lock(l_DowntimeMutex);
-
-       return l_NextDowntimeID;
-}
-
-String Checkable::AddDowntime(const String& author, const String& comment,
-    double startTime, double endTime, bool fixed,
-    const String& triggeredBy, double duration, const String& scheduledBy,
-    const String& id, const MessageOrigin::Ptr& origin)
-{
-       String uid;
-
-       if (id.IsEmpty())
-               uid = Utility::NewUniqueID();
-       else
-               uid = id;
-
-       Downtime::Ptr downtime = new Downtime();
-       downtime->SetId(uid);
-       downtime->SetEntryTime(Utility::GetTime());
-       downtime->SetAuthor(author);
-       downtime->SetComment(comment);
-       downtime->SetStartTime(startTime);
-       downtime->SetEndTime(endTime);
-       downtime->SetFixed(fixed);
-       downtime->SetDuration(duration);
-       downtime->SetTriggeredBy(triggeredBy);
-       downtime->SetScheduledBy(scheduledBy);
-
-       if (!triggeredBy.IsEmpty()) {
-               Downtime::Ptr triggerDowntime = GetDowntimeByID(triggeredBy);
-
-               if (triggerDowntime)
-                       downtime->SetTriggeredByLegacyId(triggerDowntime->GetLegacyId());
-       }
-
-       int legacy_id;
-
-       {
-               boost::mutex::scoped_lock lock(l_DowntimeMutex);
-               legacy_id = l_NextDowntimeID++;
-       }
-
-       downtime->SetLegacyId(legacy_id);
-
-       if (!triggeredBy.IsEmpty()) {
-               Checkable::Ptr otherOwner = GetOwnerByDowntimeID(triggeredBy);
-               Dictionary::Ptr otherDowntimes = otherOwner->GetDowntimes();
-               Downtime::Ptr otherDowntime = otherDowntimes->Get(triggeredBy);
-               Dictionary::Ptr triggers = otherDowntime->GetTriggers();
-
-               triggers->Set(triggeredBy, triggeredBy);
-       }
-
-       GetDowntimes()->Set(uid, downtime);
-
-       {
-               boost::mutex::scoped_lock lock(l_DowntimeMutex);
-               l_LegacyDowntimesCache[legacy_id] = uid;
-               l_DowntimesCache[uid] = this;
-       }
-
-       Log(LogNotice, "Checkable")
-           << "Added downtime with ID '" << downtime->GetLegacyId()
-           << "' between '" << Utility::FormatDateTime("%Y-%m-%d %H:%M:%S", startTime)
-           << "' and '" << Utility::FormatDateTime("%Y-%m-%d %H:%M:%S", endTime) << "'.";
-
-       OnDowntimeAdded(this, downtime, origin);
-
-       /* if this object is already in a NOT-OK state trigger
-        * this downtime now *after* it has been added (important
-        * for DB IDO, etc.)
-        */
-       if (GetStateRaw() != ServiceOK) {
-               Log(LogNotice, "Checkable")
-                   << "Checkable '" << GetName() << "' already in a NOT-OK state."
-                   << " Triggering downtime now.";
-               TriggerDowntime(uid);
-       }
-
-       return uid;
-}
-
-void Checkable::RemoveDowntime(const String& id, bool cancelled, const MessageOrigin::Ptr& origin)
-{
-       Checkable::Ptr owner = GetOwnerByDowntimeID(id);
-
-       if (!owner)
-               return;
-
-       Dictionary::Ptr downtimes = owner->GetDowntimes();
-
-       Downtime::Ptr downtime = downtimes->Get(id);
-
-       if (!downtime)
-               return;
-
-       int legacy_id = downtime->GetLegacyId();
-
-       String config_owner = downtime->GetConfigOwner();
-
-       if (!config_owner.IsEmpty()) {
-               Log(LogWarning, "Checkable")
-                   << "Cannot remove downtime with ID '" << legacy_id << "'. It is owned by scheduled downtime object '" << config_owner << "'";
-               return;
-       }
-
-       downtimes->Remove(id);
-
-       {
-               boost::mutex::scoped_lock lock(l_DowntimeMutex);
-               l_LegacyDowntimesCache.erase(legacy_id);
-               l_DowntimesCache.erase(id);
-       }
-
-       downtime->SetWasCancelled(cancelled);
-
-       Log(LogNotice, "Checkable")
-           << "Removed downtime with ID '" << downtime->GetLegacyId() << "' from service '" << owner->GetName() << "'.";
-
-       OnDowntimeRemoved(owner, downtime, origin);
-}
-
 void Checkable::RemoveAllDowntimes(void)
 {
-       std::vector<String> ids;
-       Dictionary::Ptr downtimes = GetDowntimes();
-
-       {
-               ObjectLock olock(downtimes);
-               BOOST_FOREACH(const Dictionary::Pair& kv, downtimes) {
-                       ids.push_back(kv.first);
-               }
-       }
-
-       BOOST_FOREACH(const String& id, ids) {
-               RemoveDowntime(id, true);
+       BOOST_FOREACH(const Downtime::Ptr& downtime, GetDowntimes()) {
+               Downtime::RemoveDowntime(downtime->GetName(), true, true);
        }
 }
 
 void Checkable::TriggerDowntimes(void)
 {
-       Dictionary::Ptr downtimes = GetDowntimes();
-
-       std::vector<String> ids;
-
-       {
-               ObjectLock olock(downtimes);
-
-               BOOST_FOREACH(const Dictionary::Pair& kv, downtimes) {
-                       ids.push_back(kv.first);
-               }
-       }
-
-       BOOST_FOREACH(const String& id, ids) {
-               TriggerDowntime(id);
-       }
-}
-
-void Checkable::TriggerDowntime(const String& id)
-{
-       Checkable::Ptr owner = GetOwnerByDowntimeID(id);
-       Downtime::Ptr downtime = GetDowntimeByID(id);
-
-       if (!downtime)
-               return;
-
-       if (downtime->IsActive() && downtime->IsTriggered()) {
-               Log(LogDebug, "Checkable")
-                   << "Not triggering downtime with ID '" << downtime->GetLegacyId() << "': already triggered.";
-               return;
-       }
-
-       if (downtime->IsExpired()) {
-               Log(LogDebug, "Checkable")
-                   << "Not triggering downtime with ID '" << downtime->GetLegacyId() << "': expired.";
-               return;
-       }
-
-       double now = Utility::GetTime();
-
-        if (now < downtime->GetStartTime() || now > downtime->GetEndTime()) {
-               Log(LogDebug, "Checkable")
-                   << "Not triggering downtime with ID '" << downtime->GetLegacyId() << "': current time is outside downtime window.";
-               return;
-       }
-
-       Log(LogNotice, "Checkable")
-               << "Triggering downtime with ID '" << downtime->GetLegacyId() << "'.";
-
-       if (downtime->GetTriggerTime() == 0)
-               downtime->SetTriggerTime(Utility::GetTime());
-
-       Dictionary::Ptr triggers = downtime->GetTriggers();
-
-       {
-               ObjectLock olock(triggers);
-               BOOST_FOREACH(const Dictionary::Pair& kv, triggers) {
-                       TriggerDowntime(kv.first);
-               }
-       }
-
-       OnDowntimeTriggered(owner, downtime);
-}
-
-String Checkable::GetDowntimeIDFromLegacyID(int id)
-{
-       boost::mutex::scoped_lock lock(l_DowntimeMutex);
-
-       std::map<int, String>::iterator it = l_LegacyDowntimesCache.find(id);
-
-       if (it == l_LegacyDowntimesCache.end())
-               return Empty;
-
-       return it->second;
-}
-
-Checkable::Ptr Checkable::GetOwnerByDowntimeID(const String& id)
-{
-       boost::mutex::scoped_lock lock(l_DowntimeMutex);
-       return l_DowntimesCache[id];
-}
-
-Downtime::Ptr Checkable::GetDowntimeByID(const String& id)
-{
-       Checkable::Ptr owner = GetOwnerByDowntimeID(id);
-
-       if (!owner)
-               return Downtime::Ptr();
-
-       Dictionary::Ptr downtimes = owner->GetDowntimes();
-
-       if (downtimes)
-               return downtimes->Get(id);
-
-       return Downtime::Ptr();
-}
-
-void Checkable::StartDowntimesExpiredTimer(void)
-{
-       l_DowntimesExpireTimer = new Timer();
-       l_DowntimesExpireTimer->SetInterval(60);
-       l_DowntimesExpireTimer->OnTimerExpired.connect(boost::bind(&Checkable::DowntimesExpireTimerHandler));
-       l_DowntimesExpireTimer->Start();
-}
-
-void Checkable::AddDowntimesToCache(void)
-{
-#ifdef I2_DEBUG
-       Log(LogDebug, "Checkable", "Updating Checkable downtimes cache.");
-#endif /* I2_DEBUG */
-
-       Dictionary::Ptr downtimes = GetDowntimes();
-
-       boost::mutex::scoped_lock lock(l_DowntimeMutex);
-
-       ObjectLock olock(downtimes);
-
-       BOOST_FOREACH(const Dictionary::Pair& kv, downtimes) {
-               Downtime::Ptr downtime = kv.second;
-
-               int legacy_id = downtime->GetLegacyId();
-
-               if (legacy_id >= l_NextDowntimeID)
-                       l_NextDowntimeID = legacy_id + 1;
-
-               l_LegacyDowntimesCache[legacy_id] = kv.first;
-               l_DowntimesCache[kv.first] = this;
-       }
-}
-
-void Checkable::RemoveExpiredDowntimes(void)
-{
-       Dictionary::Ptr downtimes = GetDowntimes();
-
-       std::vector<String> expiredDowntimes;
-
-       {
-               ObjectLock olock(downtimes);
-
-               BOOST_FOREACH(const Dictionary::Pair& kv, downtimes) {
-                       Downtime::Ptr downtime = kv.second;
-
-                       if (downtime->IsExpired())
-                               expiredDowntimes.push_back(kv.first);
-               }
-       }
-
-       BOOST_FOREACH(const String& id, expiredDowntimes) {
-               /* override config owner to clear expired downtimes once */
-               Downtime::Ptr downtime = GetDowntimeByID(id);
-               downtime->SetConfigOwner(Empty);
-
-               RemoveDowntime(id, false);
-       }
-}
-
-void Checkable::DowntimesExpireTimerHandler(void)
-{
-       BOOST_FOREACH(const Host::Ptr& host, ConfigType::GetObjectsByType<Host>()) {
-               host->RemoveExpiredDowntimes();
-       }
-
-       BOOST_FOREACH(const Service::Ptr& service, ConfigType::GetObjectsByType<Service>()) {
-               service->RemoveExpiredDowntimes();
+       BOOST_FOREACH(const Downtime::Ptr& downtime, GetDowntimes()) {
+               downtime->TriggerDowntime();
        }
 }
 
 bool Checkable::IsInDowntime(void) const
 {
-       Dictionary::Ptr downtimes = GetDowntimes();
-
-       ObjectLock olock(downtimes);
-
-       BOOST_FOREACH(const Dictionary::Pair& kv, downtimes) {
-               Downtime::Ptr downtime = kv.second;
-
+       BOOST_FOREACH(const Downtime::Ptr& downtime, GetDowntimes()) {
                if (downtime->IsActive())
                        return true;
        }
@@ -369,13 +54,8 @@ bool Checkable::IsInDowntime(void) const
 int Checkable::GetDowntimeDepth(void) const
 {
        int downtime_depth = 0;
-       Dictionary::Ptr downtimes = GetDowntimes();
-
-       ObjectLock olock(downtimes);
-
-       BOOST_FOREACH(const Dictionary::Pair& kv, downtimes) {
-               Downtime::Ptr downtime = kv.second;
 
+       BOOST_FOREACH(const Downtime::Ptr& downtime, GetDowntimes()) {
                if (downtime->IsActive())
                        downtime_depth++;
        }
@@ -383,3 +63,20 @@ int Checkable::GetDowntimeDepth(void) const
        return downtime_depth;
 }
 
+std::set<Downtime::Ptr> Checkable::GetDowntimes(void) const
+{
+       boost::mutex::scoped_lock lock(m_DowntimeMutex);
+       return m_Downtimes;
+}
+
+void Checkable::RegisterDowntime(const Downtime::Ptr& downtime)
+{
+       boost::mutex::scoped_lock lock(m_DowntimeMutex);
+       m_Downtimes.insert(downtime);
+}
+
+void Checkable::UnregisterDowntime(const Downtime::Ptr& downtime)
+{
+       boost::mutex::scoped_lock lock(m_DowntimeMutex);
+       m_Downtimes.erase(downtime);
+}
index 160431f563e2ad73fac0e135c2aae9154e68a300..7e7cf370af9b92006ee5e1421820f34003b35ad8 100644 (file)
@@ -88,13 +88,13 @@ std::set<Notification::Ptr> Checkable::GetNotifications(void) const
        return m_Notifications;
 }
 
-void Checkable::AddNotification(const Notification::Ptr& notification)
+void Checkable::RegisterNotification(const Notification::Ptr& notification)
 {
        boost::mutex::scoped_lock lock(m_NotificationMutex);
        m_Notifications.insert(notification);
 }
 
-void Checkable::RemoveNotification(const Notification::Ptr& notification)
+void Checkable::UnregisterNotification(const Notification::Ptr& notification)
 {
        boost::mutex::scoped_lock lock(m_NotificationMutex);
        m_Notifications.erase(notification);
index fd985e995b171e6474c69b70aa387c1c0f12618d..9ebf748f62d34947b35f8b2aab665947c4360831 100644 (file)
@@ -40,42 +40,14 @@ Checkable::Checkable(void)
        SetSchedulingOffset(Utility::Random());
 }
 
-void Checkable::Start(void)
+void Checkable::Start(bool runtimeCreated)
 {
        double now = Utility::GetTime();
 
        if (GetNextCheck() < now + 300)
                UpdateNextCheck();
 
-       ObjectImpl<Checkable>::Start();
-}
-
-void Checkable::OnStateLoaded(void)
-{
-       AddDowntimesToCache();
-       AddCommentsToCache();
-
-       std::vector<String> ids;
-       Dictionary::Ptr downtimes = GetDowntimes();
-
-       {
-               ObjectLock dlock(downtimes);
-               BOOST_FOREACH(const Dictionary::Pair& kv, downtimes) {
-                       Downtime::Ptr downtime = kv.second;
-
-                       if (downtime->GetScheduledBy().IsEmpty())
-                               continue;
-
-                       ids.push_back(kv.first);
-               }
-       }
-
-       BOOST_FOREACH(const String& id, ids) {
-               /* override config owner to clear downtimes once */
-               Downtime::Ptr downtime = GetDowntimeByID(id);
-               downtime->SetConfigOwner(Empty);
-               RemoveDowntime(id, true);
-       }
+       ObjectImpl<Checkable>::Start(runtimeCreated);
 }
 
 void Checkable::AddGroup(const String& name)
index cf828af93793542c8ddc5de5617da776cd84ff4d..58e90a9cbbe501aad8d2481dc8164c8b5444dae7 100644 (file)
@@ -75,8 +75,6 @@ public:
 
        void AddGroup(const String& name);
 
-       //bool IsHostCheck(void) const;
-
        bool IsReachable(DependencyType dt = DependencyState, intrusive_ptr<Dependency> *failedDependency = NULL, int rstack = 0) const;
 
        AcknowledgementType GetAcknowledgement(void);
@@ -124,62 +122,37 @@ public:
        static boost::signals2::signal<void (const Notification::Ptr&, const Checkable::Ptr&, const std::set<User::Ptr>&,
            const NotificationType&, const CheckResult::Ptr&, const String&,
            const String&)> OnNotificationSentToAllUsers;
-       static boost::signals2::signal<void (const Checkable::Ptr&, const Comment::Ptr&, const MessageOrigin::Ptr&)> OnCommentAdded;
-       static boost::signals2::signal<void (const Checkable::Ptr&, const Comment::Ptr&, const MessageOrigin::Ptr&)> OnCommentRemoved;
-       static boost::signals2::signal<void (const Checkable::Ptr&, const Downtime::Ptr&, const MessageOrigin::Ptr&)> OnDowntimeAdded;
-       static boost::signals2::signal<void (const Checkable::Ptr&, const Downtime::Ptr&, const MessageOrigin::Ptr&)> OnDowntimeRemoved;
-       static boost::signals2::signal<void (const Checkable::Ptr&, const Downtime::Ptr&)> OnDowntimeTriggered;
        static boost::signals2::signal<void (const Checkable::Ptr&, const String&, const String&, AcknowledgementType,
                                             bool, double, const MessageOrigin::Ptr&)> OnAcknowledgementSet;
        static boost::signals2::signal<void (const Checkable::Ptr&, const MessageOrigin::Ptr&)> OnAcknowledgementCleared;
        static boost::signals2::signal<void (const Checkable::Ptr&)> OnEventCommandExecuted;
 
        /* Downtimes */
-       static int GetNextDowntimeID(void);
-
        int GetDowntimeDepth(void) const;
 
-       String AddDowntime(const String& author, const String& comment,
-           double startTime, double endTime, bool fixed,
-           const String& triggeredBy, double duration,
-           const String& scheduledBy = String(), const String& id = String(),
-           const MessageOrigin::Ptr& origin = MessageOrigin::Ptr());
-
        void RemoveAllDowntimes(void);
-       static void RemoveDowntime(const String& id, bool cancelled, const MessageOrigin::Ptr& origin = MessageOrigin::Ptr());
-
        void TriggerDowntimes(void);
-       static void TriggerDowntime(const String& id);
-
-       static String GetDowntimeIDFromLegacyID(int id);
-       static Checkable::Ptr GetOwnerByDowntimeID(const String& id);
-       static Downtime::Ptr GetDowntimeByID(const String& id);
-
-       static void StartDowntimesExpiredTimer(void);
-
        bool IsInDowntime(void) const;
        bool IsAcknowledged(void);
 
-       /* Comments */
-       static int GetNextCommentID(void);
-
-       String AddComment(CommentType entryType, const String& author,
-           const String& text, double expireTime, const String& id = String(), const MessageOrigin::Ptr& origin = MessageOrigin::Ptr());
+       std::set<Downtime::Ptr> GetDowntimes(void) const;
+       void RegisterDowntime(const Downtime::Ptr& downtime);
+       void UnregisterDowntime(const Downtime::Ptr& downtime);
 
+       /* Comments */
        void RemoveAllComments(void);
        void RemoveCommentsByType(int type);
-       static void RemoveComment(const String& id, const MessageOrigin::Ptr& origin = MessageOrigin::Ptr());
 
-       static String GetCommentIDFromLegacyID(int id);
-       static Checkable::Ptr GetOwnerByCommentID(const String& id);
-       static Comment::Ptr GetCommentByID(const String& id);
+       std::set<Comment::Ptr> GetComments(void) const;
+       void RegisterComment(const Comment::Ptr& comment);
+       void UnregisterComment(const Comment::Ptr& comment);
 
        /* Notifications */
        void SendNotifications(NotificationType type, const CheckResult::Ptr& cr, const String& author = "", const String& text = "");
 
        std::set<Notification::Ptr> GetNotifications(void) const;
-       void AddNotification(const Notification::Ptr& notification);
-       void RemoveNotification(const Notification::Ptr& notification);
+       void RegisterNotification(const Notification::Ptr& notification);
+       void UnregisterNotification(const Notification::Ptr& notification);
 
        void ResetNotificationNumbers(void);
 
@@ -207,9 +180,7 @@ public:
        virtual void ValidateCheckInterval(double value, const ValidationUtils& utils) override;
 
 protected:
-       virtual void Start(void) override;
-
-       virtual void OnStateLoaded(void) override;
+       virtual void Start(bool runtimeCreated) override;
 
 private:
        mutable boost::mutex m_CheckableMutex;
@@ -217,14 +188,12 @@ private:
        long m_SchedulingOffset;
 
        /* Downtimes */
-       static void DowntimesExpireTimerHandler(void);
-       void RemoveExpiredDowntimes(void);
-       void AddDowntimesToCache(void);
+       std::set<Downtime::Ptr> m_Downtimes;
+       mutable boost::mutex m_DowntimeMutex;
 
        /* Comments */
-       static void CommentsExpireTimerHandler(void);
-       void RemoveExpiredComments(void);
-       void AddCommentsToCache(void);
+       std::set<Comment::Ptr> m_Comments;
+       mutable boost::mutex m_CommentMutex;
 
        /* Notifications */
        std::set<Notification::Ptr> m_Notifications;
index d6ed943c2e3ae7576703a06d0042c9aefae10654..433de6509fe891da2b39477e229bc6041e5241de 100644 (file)
@@ -137,12 +137,6 @@ abstract class Checkable : CustomVarObject
                default {{{ return AcknowledgementNone; }}}
        };
        [state] double acknowledgement_expiry;
-       [state, no_user_modify] Dictionary::Ptr comments {
-               default {{{ return new Dictionary(); }}}
-       };
-       [state, no_user_modify] Dictionary::Ptr downtimes {
-               default {{{ return new Dictionary(); }}}
-       };
        [state] bool force_next_notification;
        [state] int flapping_positive;
        [state] int flapping_negative;
index 1228673d86149018e956a3dbd8d5c3ab27bcb89b..e90f5e5532236a2b4aa79f81822b7b803e5ad3fa 100644 (file)
@@ -44,10 +44,6 @@ REGISTER_APIFUNCTION(SetNextCheck, event, &ClusterEvents::NextCheckChangedAPIHan
 REGISTER_APIFUNCTION(SetNextNotification, event, &ClusterEvents::NextNotificationChangedAPIHandler);
 REGISTER_APIFUNCTION(SetForceNextCheck, event, &ClusterEvents::ForceNextCheckChangedAPIHandler);
 REGISTER_APIFUNCTION(SetForceNextNotification, event, &ClusterEvents::ForceNextNotificationChangedAPIHandler);
-REGISTER_APIFUNCTION(AddComment, event, &ClusterEvents::CommentAddedAPIHandler);
-REGISTER_APIFUNCTION(RemoveComment, event, &ClusterEvents::CommentRemovedAPIHandler);
-REGISTER_APIFUNCTION(AddDowntime, event, &ClusterEvents::DowntimeAddedAPIHandler);
-REGISTER_APIFUNCTION(RemoveDowntime, event, &ClusterEvents::DowntimeRemovedAPIHandler);
 REGISTER_APIFUNCTION(SetAcknowledgement, event, &ClusterEvents::AcknowledgementSetAPIHandler);
 REGISTER_APIFUNCTION(ClearAcknowledgement, event, &ClusterEvents::AcknowledgementClearedAPIHandler);
 REGISTER_APIFUNCTION(UpdateRepository, event, &ClusterEvents::UpdateRepositoryAPIHandler);
@@ -63,10 +59,6 @@ void ClusterEvents::StaticInitialize(void)
        Checkable::OnForceNextCheckChanged.connect(&ClusterEvents::ForceNextCheckChangedHandler);
        Checkable::OnForceNextNotificationChanged.connect(&ClusterEvents::ForceNextNotificationChangedHandler);
 
-       Checkable::OnCommentAdded.connect(&ClusterEvents::CommentAddedHandler);
-       Checkable::OnCommentRemoved.connect(&ClusterEvents::CommentRemovedHandler);
-       Checkable::OnDowntimeAdded.connect(&ClusterEvents::DowntimeAddedHandler);
-       Checkable::OnDowntimeRemoved.connect(&ClusterEvents::DowntimeRemovedHandler);
        Checkable::OnAcknowledgementSet.connect(&ClusterEvents::AcknowledgementSetHandler);
        Checkable::OnAcknowledgementCleared.connect(&ClusterEvents::AcknowledgementClearedHandler);
 
@@ -423,273 +415,6 @@ Value ClusterEvents::ForceNextNotificationChangedAPIHandler(const MessageOrigin:
        return Empty;
 }
 
-void ClusterEvents::CommentAddedHandler(const Checkable::Ptr& checkable, const Comment::Ptr& comment, const MessageOrigin::Ptr& origin)
-{
-       ApiListener::Ptr listener = ApiListener::GetInstance();
-
-       if (!listener)
-               return;
-
-       Host::Ptr host;
-       Service::Ptr service;
-       tie(host, service) = GetHostService(checkable);
-
-       Dictionary::Ptr params = new Dictionary();
-       params->Set("host", host->GetName());
-       if (service)
-               params->Set("service", service->GetShortName());
-       params->Set("comment", Serialize(comment));
-
-       Dictionary::Ptr message = new Dictionary();
-       message->Set("jsonrpc", "2.0");
-       message->Set("method", "event::AddComment");
-       message->Set("params", params);
-
-       listener->RelayMessage(origin, checkable, message, true);
-}
-
-Value ClusterEvents::CommentAddedAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params)
-{
-       Endpoint::Ptr endpoint = origin->FromClient->GetEndpoint();
-
-       if (!endpoint) {
-               Log(LogNotice, "ClusterEvents")
-                   << "Discarding 'comment added' message from '" << origin->FromClient->GetIdentity() << "': Invalid endpoint origin (client not allowed).";
-               return Empty;
-       }
-
-       if (!params)
-               return Empty;
-
-       Host::Ptr host = Host::GetByName(params->Get("host"));
-
-       if (!host)
-               return Empty;
-
-       Checkable::Ptr checkable;
-
-       if (params->Contains("service"))
-               checkable = host->GetServiceByShortName(params->Get("service"));
-       else
-               checkable = host;
-
-       if (!checkable)
-               return Empty;
-
-       if (origin->FromZone && !origin->FromZone->CanAccessObject(checkable)) {
-               Log(LogNotice, "ClusterEvents")
-                   << "Discarding 'comment added' message from '" << origin->FromClient->GetIdentity() << "': Unauthorized access.";
-               return Empty;
-       }
-
-       Comment::Ptr comment = new Comment();
-       Deserialize(comment, params->Get("comment"), true);
-
-       checkable->AddComment(comment->GetEntryType(), comment->GetAuthor(),
-           comment->GetText(), comment->GetExpireTime(), comment->GetId(), origin);
-
-       return Empty;
-}
-
-void ClusterEvents::CommentRemovedHandler(const Checkable::Ptr& checkable, const Comment::Ptr& comment, const MessageOrigin::Ptr& origin)
-{
-       ApiListener::Ptr listener = ApiListener::GetInstance();
-
-       if (!listener)
-               return;
-
-       Host::Ptr host;
-       Service::Ptr service;
-       tie(host, service) = GetHostService(checkable);
-
-       Dictionary::Ptr params = new Dictionary();
-       params->Set("host", host->GetName());
-       if (service)
-               params->Set("service", service->GetShortName());
-       params->Set("id", comment->GetId());
-
-       Dictionary::Ptr message = new Dictionary();
-       message->Set("jsonrpc", "2.0");
-       message->Set("method", "event::RemoveComment");
-       message->Set("params", params);
-
-       listener->RelayMessage(origin, checkable, message, true);
-}
-
-Value ClusterEvents::CommentRemovedAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params)
-{
-       Endpoint::Ptr endpoint = origin->FromClient->GetEndpoint();
-
-       if (!endpoint) {
-               Log(LogNotice, "ClusterEvents")
-                   << "Discarding 'comment removed' message from '" << origin->FromClient->GetIdentity() << "': Invalid endpoint origin (client not allowed).";
-               return Empty;
-       }
-
-       if (!params)
-               return Empty;
-
-       Host::Ptr host = Host::GetByName(params->Get("host"));
-
-       if (!host)
-               return Empty;
-
-       Checkable::Ptr checkable;
-
-       if (params->Contains("service"))
-               checkable = host->GetServiceByShortName(params->Get("service"));
-       else
-               checkable = host;
-
-       if (!checkable)
-               return Empty;
-
-       if (origin->FromZone && !origin->FromZone->CanAccessObject(checkable)) {
-               Log(LogNotice, "ClusterEvents")
-                   << "Discarding 'comment removed' message from '" << origin->FromClient->GetIdentity() << "': Unauthorized access.";
-               return Empty;
-       }
-
-       checkable->RemoveComment(params->Get("id"), origin);
-
-       return Empty;
-}
-
-void ClusterEvents::DowntimeAddedHandler(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime, const MessageOrigin::Ptr& origin)
-{
-       ApiListener::Ptr listener = ApiListener::GetInstance();
-
-       if (!listener)
-               return;
-
-       Host::Ptr host;
-       Service::Ptr service;
-       tie(host, service) = GetHostService(checkable);
-
-       Dictionary::Ptr params = new Dictionary();
-       params->Set("host", host->GetName());
-       if (service)
-               params->Set("service", service->GetShortName());
-       params->Set("downtime", Serialize(downtime));
-
-       Dictionary::Ptr message = new Dictionary();
-       message->Set("jsonrpc", "2.0");
-       message->Set("method", "event::AddDowntime");
-       message->Set("params", params);
-
-       listener->RelayMessage(origin, checkable, message, true);
-}
-
-Value ClusterEvents::DowntimeAddedAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params)
-{
-       Endpoint::Ptr endpoint = origin->FromClient->GetEndpoint();
-
-       if (!endpoint) {
-               Log(LogNotice, "ClusterEvents")
-                   << "Discarding 'downtime added' message from '" << origin->FromClient->GetIdentity() << "': Invalid endpoint origin (client not allowed).";
-               return Empty;
-       }
-
-       if (!params)
-               return Empty;
-
-       Host::Ptr host = Host::GetByName(params->Get("host"));
-
-       if (!host)
-               return Empty;
-
-       Checkable::Ptr checkable;
-
-       if (params->Contains("service"))
-               checkable = host->GetServiceByShortName(params->Get("service"));
-       else
-               checkable = host;
-
-       if (!checkable)
-               return Empty;
-
-       if (origin->FromZone && !origin->FromZone->CanAccessObject(checkable)) {
-               Log(LogNotice, "ClusterEvents")
-                   << "Discarding 'downtime added' message from '" << origin->FromClient->GetIdentity() << "': Unauthorized access.";
-               return Empty;
-       }
-
-       Downtime::Ptr downtime = new Downtime();
-       Deserialize(downtime, params->Get("downtime"), true);
-
-       checkable->AddDowntime(downtime->GetAuthor(), downtime->GetComment(),
-           downtime->GetStartTime(), downtime->GetEndTime(),
-           downtime->GetFixed(), downtime->GetTriggeredBy(),
-           downtime->GetDuration(), downtime->GetScheduledBy(),
-           downtime->GetId(), origin);
-
-       return Empty;
-}
-
-void ClusterEvents::DowntimeRemovedHandler(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime, const MessageOrigin::Ptr& origin)
-{
-       ApiListener::Ptr listener = ApiListener::GetInstance();
-
-       if (!listener)
-               return;
-
-       Host::Ptr host;
-       Service::Ptr service;
-       tie(host, service) = GetHostService(checkable);
-
-       Dictionary::Ptr params = new Dictionary();
-       params->Set("host", host->GetName());
-       if (service)
-               params->Set("service", service->GetShortName());
-       params->Set("id", downtime->GetId());
-
-       Dictionary::Ptr message = new Dictionary();
-       message->Set("jsonrpc", "2.0");
-       message->Set("method", "event::RemoveDowntime");
-       message->Set("params", params);
-
-       listener->RelayMessage(origin, checkable, message, true);
-}
-
-Value ClusterEvents::DowntimeRemovedAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params)
-{
-       Endpoint::Ptr endpoint = origin->FromClient->GetEndpoint();
-
-       if (!endpoint) {
-               Log(LogNotice, "ClusterEvents")
-                   << "Discarding 'downtime removed' message from '" << origin->FromClient->GetIdentity() << "': Invalid endpoint origin (client not allowed).";
-               return Empty;
-       }
-
-       if (!params)
-               return Empty;
-
-       Host::Ptr host = Host::GetByName(params->Get("host"));
-
-       if (!host)
-               return Empty;
-
-       Checkable::Ptr checkable;
-
-       if (params->Contains("service"))
-               checkable = host->GetServiceByShortName(params->Get("service"));
-       else
-               checkable = host;
-
-       if (!checkable)
-               return Empty;
-
-       if (origin->FromZone && !origin->FromZone->CanAccessObject(checkable)) {
-               Log(LogNotice, "ClusterEvents")
-                   << "Discarding 'downtime removed' message from '" << origin->FromClient->GetIdentity() << "': Unauthorized access.";
-               return Empty;
-       }
-
-       checkable->RemoveDowntime(params->Get("id"), false, origin);
-
-       return Empty;
-}
-
 void ClusterEvents::AcknowledgementSetHandler(const Checkable::Ptr& checkable,
     const String& author, const String& comment, AcknowledgementType type,
     bool notify, double expiry, const MessageOrigin::Ptr& origin)
index ab6c9d166ea23638b6cf4e99c980a3c9f5a177c1..4087a4262705e7eaa8365ac28f87664a05fd9aa2 100644 (file)
@@ -52,18 +52,6 @@ public:
        static void ForceNextNotificationChangedHandler(const Checkable::Ptr& checkable, const MessageOrigin::Ptr& origin);
        static Value ForceNextNotificationChangedAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params);
 
-       static void CommentAddedHandler(const Checkable::Ptr& checkable, const Comment::Ptr& comment, const MessageOrigin::Ptr& origin);
-       static Value CommentAddedAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params);
-
-       static void CommentRemovedHandler(const Checkable::Ptr& checkable, const Comment::Ptr& comment, const MessageOrigin::Ptr& origin);
-       static Value CommentRemovedAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params);
-
-       static void DowntimeAddedHandler(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime, const MessageOrigin::Ptr& origin);
-       static Value DowntimeAddedAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params);
-
-       static void DowntimeRemovedHandler(const Checkable::Ptr& checkable, const Downtime::Ptr& downtime, const MessageOrigin::Ptr& origin);
-       static Value DowntimeRemovedAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params);
-
        static void AcknowledgementSetHandler(const Checkable::Ptr& checkable, const String& author, const String& comment, AcknowledgementType type,
            bool notify, double expiry, const MessageOrigin::Ptr& origin);
        static Value AcknowledgementSetAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params);
index bdbfcc50e27f63c8aaaf6e5156a3aa68aecbc742..5f69e669e4c9749249c0b1a39373829d496942ff 100644 (file)
 
 #include "icinga/comment.hpp"
 #include "icinga/comment.tcpp"
+#include "icinga/host.hpp"
+#include "remote/configobjectutility.hpp"
 #include "base/utility.hpp"
 #include "base/configtype.hpp"
+#include "base/timer.hpp"
+#include <boost/foreach.hpp>
+#include <boost/algorithm/string/split.hpp>
+#include <boost/algorithm/string/classification.hpp>
 
 using namespace icinga;
 
+static int l_NextCommentID = 1;
+static boost::mutex l_CommentMutex;
+static std::map<int, String> l_LegacyCommentsCache;
+static Timer::Ptr l_CommentsExpireTimer;
+
+boost::signals2::signal<void (const Comment::Ptr&)> Comment::OnCommentAdded;
+boost::signals2::signal<void (const Comment::Ptr&)> Comment::OnCommentRemoved;
+
+INITIALIZE_ONCE(&Comment::StaticInitialize);
+
 REGISTER_TYPE(Comment);
 
+void Comment::StaticInitialize(void)
+{
+        l_CommentsExpireTimer = new Timer();
+        l_CommentsExpireTimer->SetInterval(60);
+        l_CommentsExpireTimer->OnTimerExpired.connect(boost::bind(&Comment::CommentsExpireTimerHandler));
+        l_CommentsExpireTimer->Start();
+}
+
+String CommentNameComposer::MakeName(const String& shortName, const Object::Ptr& context) const
+{
+       Comment::Ptr comment = dynamic_pointer_cast<Comment>(context);
+
+       if (!comment)
+               return "";
+
+       String name = comment->GetHostName();
+
+       if (!comment->GetServiceName().IsEmpty())
+               name += "!" + comment->GetServiceName();
+
+       name += "!" + shortName;
+
+       return name;
+}
+
+Dictionary::Ptr CommentNameComposer::ParseName(const String& name) const
+{
+       std::vector<String> tokens;
+       boost::algorithm::split(tokens, name, boost::is_any_of("!"));
+
+       if (tokens.size() < 2)
+               BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid Comment name."));
+
+       Dictionary::Ptr result = new Dictionary();
+       result->Set("host_name", tokens[0]);
+
+       if (tokens.size() > 2) {
+               result->Set("service_name", tokens[1]);
+               result->Set("name", tokens[2]);
+       } else {
+               result->Set("name", tokens[1]);
+       }
+
+       return result;
+}
+
+void Comment::OnAllConfigLoaded(void)
+{
+       ConfigObject::OnAllConfigLoaded();
+
+       Host::Ptr host = Host::GetByName(GetHostName());
+
+       if (GetServiceName().IsEmpty())
+               m_Checkable = host;
+       else
+               m_Checkable = host->GetServiceByShortName(GetServiceName());
+
+       if (!m_Checkable)
+               BOOST_THROW_EXCEPTION(ScriptError("Comment '" + GetName() + "' references a host/service which doesn't exist.", GetDebugInfo()));
+}
+
+void Comment::Start(bool runtimeCreated)
+{
+       ObjectImpl<Comment>::Start(runtimeCreated);
+
+       {
+               boost::mutex::scoped_lock lock(l_CommentMutex);
+
+                SetLegacyId(l_NextCommentID);
+                l_LegacyCommentsCache[l_NextCommentID] = GetName();
+                l_NextCommentID++;
+       }
+
+       GetCheckable()->RegisterComment(this);
+
+       if (runtimeCreated)
+               OnCommentAdded(this);
+}
+
+void Comment::Stop(bool runtimeRemoved)
+{
+       GetCheckable()->UnregisterComment(this);
+
+       if (runtimeRemoved)
+               OnCommentRemoved(this);
+
+       ObjectImpl<Comment>::Stop(runtimeRemoved);
+}
+
+Checkable::Ptr Comment::GetCheckable(void) const
+{
+       return m_Checkable;
+}
+
 bool Comment::IsExpired(void) const
 {
        double expire_time = GetExpireTime();
 
        return (expire_time != 0 && expire_time < Utility::GetTime());
 }
+
+int Comment::GetNextCommentID(void)
+{
+       boost::mutex::scoped_lock lock(l_CommentMutex);
+
+       return l_NextCommentID;
+}
+
+String Comment::AddComment(const Checkable::Ptr& checkable, CommentType entryType, const String& author,
+    const String& text, double expireTime, const String& id, const MessageOrigin::Ptr& origin)
+{
+       String fullName;
+
+        if (id.IsEmpty())
+                fullName = checkable->GetName() + "!" + Utility::NewUniqueID();
+        else
+                fullName = id;
+
+        Dictionary::Ptr attrs = new Dictionary();
+
+        attrs->Set("author", author);
+        attrs->Set("text", text);
+        attrs->Set("expire_time", expireTime);
+        attrs->Set("entry_type", entryType);
+
+        Host::Ptr host;
+        Service::Ptr service;
+        tie(host, service) = GetHostService(checkable);
+
+        attrs->Set("host_name", host->GetName());
+        if (service)
+                attrs->Set("service_name", service->GetShortName());
+
+        String config = ConfigObjectUtility::CreateObjectConfig(Comment::TypeInstance, fullName, true, Array::Ptr(), attrs);
+
+        Array::Ptr errors = new Array();
+
+        if (!ConfigObjectUtility::CreateObject(Comment::TypeInstance, fullName, config, errors)) {
+                ObjectLock olock(errors);
+                BOOST_FOREACH(const String& error, errors) {
+                        Log(LogCritical, "Comment", error);
+                }
+
+                BOOST_THROW_EXCEPTION(std::runtime_error("Could not create comment."));
+        }
+
+       Comment::Ptr comment = Comment::GetByName(fullName);
+
+        Log(LogNotice, "Comment")
+            << "Added comment '" << comment->GetName() << "'.";
+
+       return fullName;
+}
+
+void Comment::RemoveComment(const String& id, const MessageOrigin::Ptr& origin)
+{
+       Comment::Ptr comment = Comment::GetByName(id);
+
+       if (!comment)
+               return;
+
+       int legacy_id = comment->GetLegacyId();
+
+        Log(LogNotice, "Comment")
+            << "Removed comment '" << comment->GetName() << "' from object '" << comment->GetCheckable()->GetName() << "'.";
+
+        Array::Ptr errors = new Array();
+
+        if (!ConfigObjectUtility::DeleteObject(comment, false, errors)) {
+                ObjectLock olock(errors);
+                BOOST_FOREACH(const String& error, errors) {
+                        Log(LogCritical, "Comment", error);
+                }
+
+                BOOST_THROW_EXCEPTION(std::runtime_error("Could not remove comment."));
+        }
+}
+
+String Comment::GetCommentIDFromLegacyID(int id)
+{
+       boost::mutex::scoped_lock lock(l_CommentMutex);
+
+       std::map<int, String>::iterator it = l_LegacyCommentsCache.find(id);
+
+       if (it == l_LegacyCommentsCache.end())
+               return Empty;
+
+       return it->second;
+}
+
+void Comment::CommentsExpireTimerHandler(void)
+{
+        std::vector<Comment::Ptr> comments;
+
+        BOOST_FOREACH(const Comment::Ptr& comment, ConfigType::GetObjectsByType<Comment>()) {
+                comments.push_back(comment);
+        }
+
+        BOOST_FOREACH(const Comment::Ptr& comment, comments) {
+                if (comment->IsExpired())
+                        RemoveComment(comment->GetName());
+        }
+}
index cb6d65f098e3f1485aaabc156b187cfb710d7143..052d8b353ec2c488afb274131008c7c772a29bde 100644 (file)
 
 #include "icinga/i2-icinga.hpp"
 #include "icinga/comment.thpp"
+#include "remote/messageorigin.hpp"
 
 namespace icinga
 {
 
+class Checkable;
+
 /**
- * A service comment.
+ * A comment.
  *
  * @ingroup icinga
  */
@@ -35,8 +38,36 @@ class I2_ICINGA_API Comment : public ObjectImpl<Comment>
 {
 public:
        DECLARE_OBJECT(Comment);
+       DECLARE_OBJECTNAME(Comment);
+
+       static boost::signals2::signal<void (const Comment::Ptr&)> OnCommentAdded;
+       static boost::signals2::signal<void (const Comment::Ptr&)> OnCommentRemoved;
+
+       intrusive_ptr<Checkable> GetCheckable(void) const;
 
        bool IsExpired(void) const;
+
+       static int GetNextCommentID(void);
+
+       static String AddComment(const intrusive_ptr<Checkable>& checkable, CommentType entryType,
+           const String& author, const String& text, double expireTime,
+           const String& id = String(), const MessageOrigin::Ptr& origin = MessageOrigin::Ptr());
+
+       static void RemoveComment(const String& id, const MessageOrigin::Ptr& origin = MessageOrigin::Ptr());
+
+       static String GetCommentIDFromLegacyID(int id);
+
+       static void StaticInitialize(void);
+
+protected:
+       virtual void OnAllConfigLoaded(void) override;
+        virtual void Start(bool runtimeCreated) override;
+        virtual void Stop(bool runtimeRemoved) override;
+
+private:
+       intrusive_ptr<Checkable> m_Checkable;
+
+        static void CommentsExpireTimerHandler(void);
 };
 
 }
index c05dc0d62930f98f014c049e33487425d0c8c4fb..a3b711a5994fd6036c8c2bc1d4e20cb6f966d6ca 100644 (file)
  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
  ******************************************************************************/
 
+#include "base/configobject.hpp"
+#include "base/utility.hpp"
+#impl_include "icinga/service.hpp"
+
 library icinga;
 
 namespace icinga
@@ -35,17 +39,56 @@ enum CommentType
        CommentFlapping = 3,
        CommentAcknowledgement = 4
 };
+
+class I2_ICINGA_API CommentNameComposer : public NameComposer
+{
+public:
+       virtual String MakeName(const String& shortName, const Object::Ptr& context) const;
+       virtual Dictionary::Ptr ParseName(const String& name) const;
+};
 }}}
 
-class Comment
+class Comment : ConfigObject < CommentNameComposer
 {
-       [state] String id;
-       [state] double entry_time;
-       [state, enum] CommentType entry_type;
-       [state] String author;
-       [state] String text;
-       [state] double expire_time;
-       [state] int legacy_id;
+       load_after Host;
+       load_after Service;
+
+       [config, protected, required, navigation(host)] name(Host) host_name {
+               navigate {{{
+                       return Host::GetByName(GetHostName());
+               }}}
+       };
+       [config, protected, navigation(service)] String service_name {
+               track {{{
+                       if (!oldValue.IsEmpty()) {
+                               Service::Ptr service = Service::GetByNamePair(GetHostName(), oldValue);
+                               DependencyGraph::RemoveDependency(this, service.get());
+                       }
+
+                       if (!newValue.IsEmpty()) {
+                               Service::Ptr service = Service::GetByNamePair(GetHostName(), newValue);
+                               DependencyGraph::RemoveDependency(this, service.get());
+                       }
+               }}}
+               navigate {{{
+                       if (GetServiceName().IsEmpty())
+                               return Service::Ptr();
+
+                       Host::Ptr host = Host::GetByName(GetHostName());
+                       return host->GetServiceByShortName(GetServiceName());
+               }}}
+       };
+
+       [config] double entry_time {
+               default {{{ return Utility::GetTime(); }}}
+       };
+       [config, enum] CommentType entry_type {
+               default {{{ return CommentUser; }}}
+       };
+       [config, required] String author;
+       [config, required] String text;
+       [config] double expire_time;
+       int legacy_id;
 };
 
 }
index 45f275b49c86eeaec854de6f6eab94114b9dab34..b670cce6a8e066bf93a454f93efcf1a3bbe1ca78 100644 (file)
@@ -123,9 +123,9 @@ void Dependency::OnAllConfigLoaded(void)
        m_Parent->AddReverseDependency(this);
 }
 
-void Dependency::Stop(void)
+void Dependency::Stop(bool runtimeRemoved)
 {
-       ObjectImpl<Dependency>::Stop();
+       ObjectImpl<Dependency>::Stop(runtimeRemoved);
 
        GetChild()->RemoveDependency(this);
        GetParent()->RemoveReverseDependency(this);
index 8a85de1734a4ead8979264d21382addfe661c10b..3ed4b1458010444be4f37ac6f91e6f7a300b0e8f 100644 (file)
@@ -59,7 +59,7 @@ public:
 protected:
        virtual void OnConfigLoaded(void) override;
        virtual void OnAllConfigLoaded(void) override;
-       virtual void Stop(void) override;
+       virtual void Stop(bool runtimeRemoved) override;
 
 private:
        Checkable::Ptr m_Parent;
index 8c37a3d03d12873315a90e3967852a88e68974f7..b418e93903a5fe8f0f9392632f5fbb0d88c903f3 100644 (file)
 
 #include "icinga/downtime.hpp"
 #include "icinga/downtime.tcpp"
+#include "icinga/host.hpp"
+#include "remote/configobjectutility.hpp"
+#include "base/configtype.hpp"
 #include "base/utility.hpp"
+#include "base/timer.hpp"
+#include <boost/foreach.hpp>
+#include <boost/algorithm/string/split.hpp>
+#include <boost/algorithm/string/classification.hpp>
 
 using namespace icinga;
 
+static int l_NextDowntimeID = 1;
+static boost::mutex l_DowntimeMutex;
+static std::map<int, String> l_LegacyDowntimesCache;
+static Timer::Ptr l_DowntimesExpireTimer;
+
+boost::signals2::signal<void (const Downtime::Ptr&)> Downtime::OnDowntimeAdded;
+boost::signals2::signal<void (const Downtime::Ptr&)> Downtime::OnDowntimeRemoved;
+boost::signals2::signal<void (const Downtime::Ptr&)> Downtime::OnDowntimeTriggered;
+
+INITIALIZE_ONCE(&Downtime::StaticInitialize);
+
 REGISTER_TYPE(Downtime);
 
+void Downtime::StaticInitialize(void)
+{
+       l_DowntimesExpireTimer = new Timer();
+       l_DowntimesExpireTimer->SetInterval(60);
+       l_DowntimesExpireTimer->OnTimerExpired.connect(boost::bind(&Downtime::DowntimesExpireTimerHandler));
+       l_DowntimesExpireTimer->Start();
+}
+
+String DowntimeNameComposer::MakeName(const String& shortName, const Object::Ptr& context) const
+{
+       Downtime::Ptr downtime = dynamic_pointer_cast<Downtime>(context);
+
+       if (!downtime)
+               return "";
+
+       String name = downtime->GetHostName();
+
+       if (!downtime->GetServiceName().IsEmpty())
+               name += "!" + downtime->GetServiceName();
+
+       name += "!" + shortName;
+
+       return name;
+}
+
+Dictionary::Ptr DowntimeNameComposer::ParseName(const String& name) const
+{
+       std::vector<String> tokens;
+       boost::algorithm::split(tokens, name, boost::is_any_of("!"));
+
+       if (tokens.size() < 2)
+               BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid Downtime name."));
+
+       Dictionary::Ptr result = new Dictionary();
+       result->Set("host_name", tokens[0]);
+
+       if (tokens.size() > 2) {
+               result->Set("service_name", tokens[1]);
+               result->Set("name", tokens[2]);
+       } else {
+               result->Set("name", tokens[1]);
+       }
+
+       return result;
+}
+
+void Downtime::OnAllConfigLoaded(void)
+{
+       ObjectImpl<Downtime>::OnAllConfigLoaded();
+
+       Host::Ptr host = Host::GetByName(GetHostName());
+
+       if (GetServiceName().IsEmpty())
+               m_Checkable = host;
+       else
+               m_Checkable = host->GetServiceByShortName(GetServiceName());
+
+       if (!m_Checkable)
+               BOOST_THROW_EXCEPTION(ScriptError("Downtime '" + GetName() + "' references a host/service which doesn't exist.", GetDebugInfo()));
+}
+
+void Downtime::Start(bool runtimeCreated)
+{
+       ObjectImpl<Downtime>::Start(runtimeCreated);
+
+       {
+               boost::mutex::scoped_lock lock(l_DowntimeMutex);
+
+               SetLegacyId(l_NextDowntimeID);
+               l_LegacyDowntimesCache[l_NextDowntimeID] = GetName();
+               l_NextDowntimeID++;
+       }
+
+       Checkable::Ptr checkable = GetCheckable();
+
+       checkable->RegisterDowntime(this);
+
+       if (runtimeCreated)
+               OnDowntimeAdded(this);
+
+       /* if this object is already in a NOT-OK state trigger
+        * this downtime now *after* it has been added (important
+        * for DB IDO, etc.)
+        */
+       if (checkable->GetStateRaw() != ServiceOK) {
+               Log(LogNotice, "Downtime")
+                   << "Checkable '" << checkable->GetName() << "' already in a NOT-OK state."
+                   << " Triggering downtime now.";
+               TriggerDowntime();
+       }
+}
+
+void Downtime::Stop(bool runtimeRemoved)
+{
+       GetCheckable()->UnregisterDowntime(this);
+
+       if (runtimeRemoved)
+               OnDowntimeRemoved(this);
+
+       ObjectImpl<Downtime>::Stop(runtimeRemoved);
+}
+
+Checkable::Ptr Downtime::GetCheckable(void) const
+{
+       return m_Checkable;
+}
+
 bool Downtime::IsActive(void) const
 {
        double now = Utility::GetTime();
@@ -57,3 +182,189 @@ bool Downtime::IsExpired(void) const
 {
        return (GetEndTime() < Utility::GetTime());
 }
+
+int Downtime::GetNextDowntimeID(void)
+{
+       boost::mutex::scoped_lock lock(l_DowntimeMutex);
+
+       return l_NextDowntimeID;
+}
+
+String Downtime::AddDowntime(const Checkable::Ptr& checkable, const String& author,
+    const String& comment, double startTime, double endTime, bool fixed,
+    const String& triggeredBy, double duration,
+    const String& scheduledDowntime, const String& scheduledBy,
+    const String& id, const MessageOrigin::Ptr& origin)
+{
+       String fullName;
+
+       if (id.IsEmpty())
+               fullName = checkable->GetName() + "!" + Utility::NewUniqueID();
+       else
+               fullName = id;
+
+       Dictionary::Ptr attrs = new Dictionary();
+
+       attrs->Set("author", author);
+       attrs->Set("comment", comment);
+       attrs->Set("start_time", startTime);
+       attrs->Set("end_time", endTime);
+       attrs->Set("fixed", fixed);
+       attrs->Set("duration", duration);
+       attrs->Set("triggered_by", triggeredBy);
+       attrs->Set("scheduled_by", scheduledBy);
+       attrs->Set("config_owner", scheduledDowntime);
+
+       Host::Ptr host;
+       Service::Ptr service;
+       tie(host, service) = GetHostService(checkable);
+
+       attrs->Set("host_name", host->GetName());
+       if (service)
+               attrs->Set("service_name", service->GetShortName());
+
+       String config = ConfigObjectUtility::CreateObjectConfig(Downtime::TypeInstance, fullName, true, Array::Ptr(), attrs);
+
+       Array::Ptr errors = new Array();
+
+       if (!ConfigObjectUtility::CreateObject(Downtime::TypeInstance, fullName, config, errors)) {
+               ObjectLock olock(errors);
+               BOOST_FOREACH(const String& error, errors) {
+                       Log(LogCritical, "Downtime", error);
+               }
+
+               BOOST_THROW_EXCEPTION(std::runtime_error("Could not create downtime."));
+       }
+
+       if (!triggeredBy.IsEmpty()) {
+               Downtime::Ptr triggerDowntime = Downtime::GetByName(triggeredBy);
+               Array::Ptr triggers = triggerDowntime->GetTriggers();
+
+               if (!triggers->Contains(triggeredBy))
+                       triggers->Add(triggeredBy);
+       }
+
+       Downtime::Ptr downtime = Downtime::GetByName(fullName);
+
+       Log(LogNotice, "Downtime")
+           << "Added downtime '" << downtime->GetName()
+           << "' between '" << Utility::FormatDateTime("%Y-%m-%d %H:%M:%S", startTime)
+           << "' and '" << Utility::FormatDateTime("%Y-%m-%d %H:%M:%S", endTime) << "'.";
+
+
+       return fullName;
+}
+
+void Downtime::RemoveDowntime(const String& id, bool cancelled, bool expired, const MessageOrigin::Ptr& origin)
+{
+       Downtime::Ptr downtime = Downtime::GetByName(id);
+
+       if (!downtime)
+               return;
+
+       String config_owner = downtime->GetConfigOwner();
+
+       if (!config_owner.IsEmpty() && !expired) {
+               Log(LogWarning, "Downtime")
+                   << "Cannot remove downtime '" << downtime->GetName() << "'. It is owned by scheduled downtime object '" << config_owner << "'";
+               return;
+       }
+
+       downtime->SetWasCancelled(cancelled);
+
+       Log(LogNotice, "Downtime")
+           << "Removed downtime '" << downtime->GetName() << "' from object '" << downtime->GetCheckable()->GetName() << "'.";
+
+       Array::Ptr errors = new Array();
+
+       if (!ConfigObjectUtility::DeleteObject(downtime, false, errors)) {
+               ObjectLock olock(errors);
+               BOOST_FOREACH(const String& error, errors) {
+                       Log(LogCritical, "Downtime", error);
+               }
+
+               BOOST_THROW_EXCEPTION(std::runtime_error("Could not remove downtime."));
+       }
+}
+
+void Downtime::TriggerDowntime(void)
+{
+       if (IsActive() && IsTriggered()) {
+               Log(LogDebug, "Downtime")
+                   << "Not triggering downtime '" << GetName() << "': already triggered.";
+               return;
+       }
+
+       if (IsExpired()) {
+               Log(LogDebug, "Downtime")
+                   << "Not triggering downtime '" << GetName() << "': expired.";
+               return;
+       }
+
+       double now = Utility::GetTime();
+
+        if (now < GetStartTime() || now > GetEndTime()) {
+               Log(LogDebug, "Downtime")
+                   << "Not triggering downtime '" << GetName() << "': current time is outside downtime window.";
+               return;
+       }
+
+       Log(LogNotice, "Downtime")
+               << "Triggering downtime '" << GetName() << "'.";
+
+       if (GetTriggerTime() == 0)
+               SetTriggerTime(Utility::GetTime());
+
+       Array::Ptr triggers = GetTriggers();
+
+       {
+               ObjectLock olock(triggers);
+               BOOST_FOREACH(const String& id, triggers) {
+                       Downtime::GetByName(id)->TriggerDowntime();
+               }
+       }
+
+       OnDowntimeTriggered(this);
+}
+
+String Downtime::GetDowntimeIDFromLegacyID(int id)
+{
+       boost::mutex::scoped_lock lock(l_DowntimeMutex);
+
+       std::map<int, String>::iterator it = l_LegacyDowntimesCache.find(id);
+
+       if (it == l_LegacyDowntimesCache.end())
+               return Empty;
+
+       return it->second;
+}
+
+void Downtime::DowntimesExpireTimerHandler(void)
+{
+       std::vector<Downtime::Ptr> downtimes;
+
+       BOOST_FOREACH(const Downtime::Ptr& downtime, ConfigType::GetObjectsByType<Downtime>()) {
+               downtimes.push_back(downtime);
+       }
+
+       BOOST_FOREACH(const Downtime::Ptr& downtime, downtimes) {
+               if (downtime->IsExpired())
+                       RemoveDowntime(downtime->GetName(), false, true);
+       }
+}
+
+void Downtime::ValidateStartTime(double value, const ValidationUtils& utils)
+{
+       ObjectImpl<Downtime>::ValidateStartTime(value, utils);
+
+       if (value <= 0)
+               BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of("start_time"), "Start time must be greater than 0."));
+}
+
+void Downtime::ValidateEndTime(double value, const ValidationUtils& utils)
+{
+       ObjectImpl<Downtime>::ValidateEndTime(value, utils);
+
+       if (value <= 0)
+               BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of("end_time"), "End time must be greater than 0."));
+}
index 2fb6337ebb773da3d9aa1294d3cada669b1836b6..25407a353bef010eee6afa594478bea81352e37e 100644 (file)
 
 #include "icinga/i2-icinga.hpp"
 #include "icinga/downtime.thpp"
+#include "remote/messageorigin.hpp"
 
 namespace icinga
 {
 
+class Checkable;
+
 /**
- * A service downtime.
+ * A downtime.
  *
  * @ingroup icinga
  */
@@ -35,11 +38,46 @@ class I2_ICINGA_API Downtime : public ObjectImpl<Downtime>
 {
 public:
        DECLARE_OBJECT(Downtime);
+       DECLARE_OBJECTNAME(Downtime);
+
+       static boost::signals2::signal<void (const Downtime::Ptr&)> OnDowntimeAdded;
+       static boost::signals2::signal<void (const Downtime::Ptr&)> OnDowntimeRemoved;
+       static boost::signals2::signal<void (const Downtime::Ptr&)> OnDowntimeTriggered;
+
+       intrusive_ptr<Checkable> GetCheckable(void) const;
 
        bool IsActive(void) const;
        bool IsTriggered(void) const;
        bool IsExpired(void) const;
 
+       static int GetNextDowntimeID(void);
+
+       static String AddDowntime(const intrusive_ptr<Checkable>& checkable, const String& author,
+           const String& comment, double startTime, double endTime, bool fixed,
+           const String& triggeredBy, double duration, const String& scheduledDowntime = String(),
+           const String& scheduledBy = String(), const String& id = String(),
+           const MessageOrigin::Ptr& origin = MessageOrigin::Ptr());
+
+       static void RemoveDowntime(const String& id, bool cancelled, bool expired = false, const MessageOrigin::Ptr& origin = MessageOrigin::Ptr());
+
+       void TriggerDowntime(void);
+
+       static String GetDowntimeIDFromLegacyID(int id);
+
+       static void StaticInitialize(void);
+
+protected:
+       virtual void OnAllConfigLoaded(void) override;
+       virtual void Start(bool runtimeCreated) override;
+       virtual void Stop(bool runtimeRemoved) override;
+
+       virtual void ValidateStartTime(double value, const ValidationUtils& utils) override;
+       virtual void ValidateEndTime(double value, const ValidationUtils& utils) override;
+
+private:
+       intrusive_ptr<Checkable> m_Checkable;
+
+       static void DowntimesExpireTimerHandler(void);
 };
 
 }
index c41c03beac56bca33f187e71459c53b9c609e155..e6be9d44338ff770e347b9ec333d0fae0a97d4c2 100644 (file)
  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
  ******************************************************************************/
 
+#include "base/configobject.hpp"
+#include "base/utility.hpp"
+#impl_include "icinga/service.hpp"
+
 library icinga;
 
 namespace icinga
 {
 
-class Downtime
+code {{{
+class I2_ICINGA_API DowntimeNameComposer : public NameComposer
+{
+public:
+       virtual String MakeName(const String& shortName, const Object::Ptr& context) const;
+       virtual Dictionary::Ptr ParseName(const String& name) const;
+};
+}}}
+
+class Downtime : ConfigObject < DowntimeNameComposer
 {
-       [state] String id;
-       [state] double entry_time;
-       [state] String author;
-       [state] String comment;
-       [state] double start_time;
-       [state] double end_time;
+       load_after Host;
+       load_after Service;
+
+       [config, protected, required, navigation(host)] name(Host) host_name {
+               navigate {{{
+                       return Host::GetByName(GetHostName());
+               }}}
+       };
+       [config, protected, navigation(service)] String service_name {
+               track {{{
+                       if (!oldValue.IsEmpty()) {
+                               Service::Ptr service = Service::GetByNamePair(GetHostName(), oldValue);
+                               DependencyGraph::RemoveDependency(this, service.get());
+                       }
+
+                       if (!newValue.IsEmpty()) {
+                               Service::Ptr service = Service::GetByNamePair(GetHostName(), newValue);
+                               DependencyGraph::RemoveDependency(this, service.get());
+                       }
+               }}}
+               navigate {{{
+                       if (GetServiceName().IsEmpty())
+                               return Service::Ptr();
+
+                       Host::Ptr host = Host::GetByName(GetHostName());
+                       return host->GetServiceByShortName(GetServiceName());
+               }}}
+       };
+
+       [state] double entry_time {
+               default {{{ return Utility::GetTime(); }}}
+       };
+       [config, required] String author;
+       [config, required] String comment;
+       [config] double start_time;
+       [config] double end_time;
        [state] double trigger_time;
-       [state] bool fixed;
-       [state] double duration;
-       [state] int triggered_by_legacy_id;
-       [state] String triggered_by;
-       [state] String scheduled_by;
-       [state] Dictionary::Ptr triggers {
-               default {{{ return new Dictionary(); }}}
+       [config] bool fixed;
+       [config] double duration;
+       [state] name(Downtime) triggered_by;
+       [config] String scheduled_by;
+       [config] Array::Ptr triggers {
+               default {{{ return new Array(); }}}
        };
-       [state] int legacy_id;
+       int legacy_id;
        [state] bool was_cancelled;
-       [state] String config_owner;
+       [config] String config_owner;
 };
 
 }
index bb99d9da2cec3eaadba9611fc9d91feee982961a..59f42353b3a6cc809af73a97254371e4d20a5f08 100644 (file)
@@ -602,7 +602,7 @@ void ExternalCommandProcessor::AcknowledgeSvcProblem(double, const std::vector<S
        Log(LogNotice, "ExternalCommandProcessor")
            << "Setting acknowledgement for service '" << service->GetName() << "'" << (notify ? "" : ". Disabled notification");
 
-       service->AddComment(CommentAcknowledgement, arguments[5], arguments[6], 0);
+       Comment::AddComment(service, CommentAcknowledgement, arguments[5], arguments[6], 0);
        service->AcknowledgeProblem(arguments[5], arguments[6], sticky ? AcknowledgementSticky : AcknowledgementNormal, notify);
 }
 
@@ -623,7 +623,7 @@ void ExternalCommandProcessor::AcknowledgeSvcProblemExpire(double, const std::ve
        Log(LogNotice, "ExternalCommandProcessor")
            << "Setting timed acknowledgement for service '" << service->GetName() << "'" << (notify ? "" : ". Disabled notification");
 
-       service->AddComment(CommentAcknowledgement, arguments[6], arguments[7], timestamp);
+       Comment::AddComment(service, CommentAcknowledgement, arguments[6], arguments[7], timestamp);
        service->AcknowledgeProblem(arguments[6], arguments[7], sticky ? AcknowledgementSticky : AcknowledgementNormal, notify, timestamp);
 }
 
@@ -661,7 +661,7 @@ void ExternalCommandProcessor::AcknowledgeHostProblem(double, const std::vector<
        if (host->GetState() == HostUp)
                BOOST_THROW_EXCEPTION(std::invalid_argument("The host '" + arguments[0] + "' is OK."));
 
-       host->AddComment(CommentAcknowledgement, arguments[4], arguments[5], 0);
+       Comment::AddComment(host, CommentAcknowledgement, arguments[4], arguments[5], 0);
        host->AcknowledgeProblem(arguments[4], arguments[5], sticky ? AcknowledgementSticky : AcknowledgementNormal, notify);
 }
 
@@ -682,7 +682,7 @@ void ExternalCommandProcessor::AcknowledgeHostProblemExpire(double, const std::v
        if (host->GetState() == HostUp)
                BOOST_THROW_EXCEPTION(std::invalid_argument("The host '" + arguments[0] + "' is OK."));
 
-       host->AddComment(CommentAcknowledgement, arguments[5], arguments[6], timestamp);
+       Comment::AddComment(host, CommentAcknowledgement, arguments[5], arguments[6], timestamp);
        host->AcknowledgeProblem(arguments[5], arguments[6], sticky ? AcknowledgementSticky : AcknowledgementNormal, notify, timestamp);
 }
 
@@ -925,11 +925,11 @@ void ExternalCommandProcessor::ScheduleSvcDowntime(double, const std::vector<Str
        int triggeredByLegacy = Convert::ToLong(arguments[5]);
        int is_fixed = Convert::ToLong(arguments[4]);
        if (triggeredByLegacy != 0)
-               triggeredBy = Service::GetDowntimeIDFromLegacyID(triggeredByLegacy);
+               triggeredBy = Downtime::GetDowntimeIDFromLegacyID(triggeredByLegacy);
 
        Log(LogNotice, "ExternalCommandProcessor")
            << "Creating downtime for service " << service->GetName();
-       (void) service->AddDowntime(arguments[7], arguments[8],
+       (void) Downtime::AddDowntime(service, arguments[7], arguments[8],
            Convert::ToDouble(arguments[2]), Convert::ToDouble(arguments[3]),
            Convert::ToBool(is_fixed), triggeredBy, Convert::ToDouble(arguments[6]));
 }
@@ -939,8 +939,8 @@ void ExternalCommandProcessor::DelSvcDowntime(double, const std::vector<String>&
        int id = Convert::ToLong(arguments[0]);
        Log(LogNotice, "ExternalCommandProcessor")
            << "Removing downtime ID " << arguments[0];
-       String rid = Service::GetDowntimeIDFromLegacyID(id);
-       Service::RemoveDowntime(rid, true);
+       String rid = Downtime::GetDowntimeIDFromLegacyID(id);
+       Downtime::RemoveDowntime(rid, true);
 }
 
 void ExternalCommandProcessor::ScheduleHostDowntime(double, const std::vector<String>& arguments)
@@ -954,12 +954,12 @@ void ExternalCommandProcessor::ScheduleHostDowntime(double, const std::vector<St
        int triggeredByLegacy = Convert::ToLong(arguments[4]);
        int is_fixed = Convert::ToLong(arguments[3]);
        if (triggeredByLegacy != 0)
-               triggeredBy = Service::GetDowntimeIDFromLegacyID(triggeredByLegacy);
+               triggeredBy = Downtime::GetDowntimeIDFromLegacyID(triggeredByLegacy);
 
        Log(LogNotice, "ExternalCommandProcessor")
            << "Creating downtime for host " << host->GetName();
 
-       (void) host->AddDowntime(arguments[6], arguments[7],
+       (void) Downtime::AddDowntime(host, arguments[6], arguments[7],
            Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
            Convert::ToBool(is_fixed), triggeredBy, Convert::ToDouble(arguments[5]));
 }
@@ -969,8 +969,8 @@ void ExternalCommandProcessor::DelHostDowntime(double, const std::vector<String>
        int id = Convert::ToLong(arguments[0]);
        Log(LogNotice, "ExternalCommandProcessor")
            << "Removing downtime ID " << arguments[0];
-       String rid = Service::GetDowntimeIDFromLegacyID(id);
-       Service::RemoveDowntime(rid, true);
+       String rid = Downtime::GetDowntimeIDFromLegacyID(id);
+       Downtime::RemoveDowntime(rid, true);
 }
 
 void ExternalCommandProcessor::DelDowntimeByHostName(double, const std::vector<String>& arguments)
@@ -996,41 +996,29 @@ void ExternalCommandProcessor::DelDowntimeByHostName(double, const std::vector<S
                Log(LogWarning, "ExternalCommandProcessor")
                    << ("Ignoring additional parameters for host '" + arguments[0] + "' downtime deletion.");
 
-       std::vector<String> ids;
+       BOOST_FOREACH(const Downtime::Ptr& downtime, host->GetDowntimes()) {
+               Log(LogNotice, "ExternalCommandProcessor")
+                   << "Removing downtime '" << downtime->GetName() << "'.";
 
-       Dictionary::Ptr hostDowntimes = host->GetDowntimes();
-       {
-               ObjectLock dhlock(hostDowntimes);
-               BOOST_FOREACH(const Dictionary::Pair& kv, hostDowntimes) {
-                       ids.push_back(kv.first);
-               }
+               Downtime::RemoveDowntime(downtime->GetName(), true);
        }
 
        BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
                if (!serviceName.IsEmpty() && serviceName != service->GetName())
                        continue;
 
-               Dictionary::Ptr serviceDowntimes = service->GetDowntimes();
-               {
-                       ObjectLock dslock(serviceDowntimes);
-                       BOOST_FOREACH(const Dictionary::Pair& kv, serviceDowntimes) {
-                               ids.push_back(kv.first);
-                       }
-               }
-       }
+               BOOST_FOREACH(const Downtime::Ptr& downtime, service->GetDowntimes()) {
+                       if (!startTime.IsEmpty() && downtime->GetStartTime() != Convert::ToDouble(startTime))
+                               continue;
 
-       BOOST_FOREACH(const String& id, ids) {
-               Downtime::Ptr downtime = Service::GetDowntimeByID(id);
+                       if (!commentString.IsEmpty() && downtime->GetComment() != commentString)
+                               continue;
 
-               if (!startTime.IsEmpty() && downtime->GetStartTime() != Convert::ToDouble(startTime))
-                       continue;
-
-               if (!commentString.IsEmpty() && downtime->GetComment() != commentString)
-                       continue;
+                       Log(LogNotice, "ExternalCommandProcessor")
+                           << "Removing downtime '" << downtime->GetName() << "'.";
 
-               Log(LogNotice, "ExternalCommandProcessor")
-                   << "Removing downtime ID " << id;
-               Service::RemoveDowntime(id, true);
+                       Downtime::RemoveDowntime(downtime->GetName(), true);
+               }
        }
 }
 
@@ -1045,19 +1033,19 @@ void ExternalCommandProcessor::ScheduleHostSvcDowntime(double, const std::vector
        int triggeredByLegacy = Convert::ToLong(arguments[4]);
        int is_fixed = Convert::ToLong(arguments[3]);
        if (triggeredByLegacy != 0)
-               triggeredBy = Service::GetDowntimeIDFromLegacyID(triggeredByLegacy);
+               triggeredBy = Downtime::GetDowntimeIDFromLegacyID(triggeredByLegacy);
 
        Log(LogNotice, "ExternalCommandProcessor")
            << "Creating downtime for host " << host->GetName();
 
-       (void) host->AddDowntime(arguments[6], arguments[7],
+       (void) Downtime::AddDowntime(host, arguments[6], arguments[7],
            Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
            Convert::ToBool(is_fixed), triggeredBy, Convert::ToDouble(arguments[5]));
 
        BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
                Log(LogNotice, "ExternalCommandProcessor")
                    << "Creating downtime for service " << service->GetName();
-               (void) service->AddDowntime(arguments[6], arguments[7],
+               (void) Downtime::AddDowntime(service, arguments[6], arguments[7],
                    Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
                    Convert::ToBool(is_fixed), triggeredBy, Convert::ToDouble(arguments[5]));
        }
@@ -1074,13 +1062,13 @@ void ExternalCommandProcessor::ScheduleHostgroupHostDowntime(double, const std::
        int triggeredByLegacy = Convert::ToLong(arguments[4]);
        int is_fixed = Convert::ToLong(arguments[3]);
        if (triggeredByLegacy != 0)
-               triggeredBy = Service::GetDowntimeIDFromLegacyID(triggeredByLegacy);
+               triggeredBy = Downtime::GetDowntimeIDFromLegacyID(triggeredByLegacy);
 
        BOOST_FOREACH(const Host::Ptr& host, hg->GetMembers()) {
                Log(LogNotice, "ExternalCommandProcessor")
                    <<  "Creating downtime for host " << host->GetName();
 
-               (void) host->AddDowntime(arguments[6], arguments[7],
+               (void) Downtime::AddDowntime(host, arguments[6], arguments[7],
                    Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
                    Convert::ToBool(is_fixed), triggeredBy, Convert::ToDouble(arguments[5]));
        }
@@ -1097,7 +1085,7 @@ void ExternalCommandProcessor::ScheduleHostgroupSvcDowntime(double, const std::v
        int triggeredByLegacy = Convert::ToLong(arguments[4]);
        int is_fixed = Convert::ToLong(arguments[3]);
        if (triggeredByLegacy != 0)
-               triggeredBy = Service::GetDowntimeIDFromLegacyID(triggeredByLegacy);
+               triggeredBy = Downtime::GetDowntimeIDFromLegacyID(triggeredByLegacy);
 
        /* Note: we can't just directly create downtimes for all the services by iterating
         * over all hosts in the host group - otherwise we might end up creating multiple
@@ -1114,7 +1102,7 @@ void ExternalCommandProcessor::ScheduleHostgroupSvcDowntime(double, const std::v
        BOOST_FOREACH(const Service::Ptr& service, services) {
                Log(LogNotice, "ExternalCommandProcessor")
                    << "Creating downtime for service " << service->GetName();
-               (void) service->AddDowntime(arguments[6], arguments[7],
+               (void) Downtime::AddDowntime(service, arguments[6], arguments[7],
                    Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
                    Convert::ToBool(is_fixed), triggeredBy, Convert::ToDouble(arguments[5]));
        }
@@ -1131,7 +1119,7 @@ void ExternalCommandProcessor::ScheduleServicegroupHostDowntime(double, const st
        int triggeredByLegacy = Convert::ToLong(arguments[4]);
        int is_fixed = Convert::ToLong(arguments[3]);
        if (triggeredByLegacy != 0)
-               triggeredBy = Service::GetDowntimeIDFromLegacyID(triggeredByLegacy);
+               triggeredBy = Downtime::GetDowntimeIDFromLegacyID(triggeredByLegacy);
 
        /* Note: we can't just directly create downtimes for all the hosts by iterating
         * over all services in the service group - otherwise we might end up creating multiple
@@ -1147,7 +1135,7 @@ void ExternalCommandProcessor::ScheduleServicegroupHostDowntime(double, const st
        BOOST_FOREACH(const Host::Ptr& host, hosts) {
                Log(LogNotice, "ExternalCommandProcessor")
                    << "Creating downtime for host " << host->GetName();
-               (void) host->AddDowntime(arguments[6], arguments[7],
+               (void) Downtime::AddDowntime(host, arguments[6], arguments[7],
                    Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
                    Convert::ToBool(is_fixed), triggeredBy, Convert::ToDouble(arguments[5]));
        }
@@ -1164,12 +1152,12 @@ void ExternalCommandProcessor::ScheduleServicegroupSvcDowntime(double, const std
        int triggeredByLegacy = Convert::ToLong(arguments[4]);
        int is_fixed = Convert::ToLong(arguments[3]);
        if (triggeredByLegacy != 0)
-               triggeredBy = Service::GetDowntimeIDFromLegacyID(triggeredByLegacy);
+               triggeredBy = Downtime::GetDowntimeIDFromLegacyID(triggeredByLegacy);
 
        BOOST_FOREACH(const Service::Ptr& service, sg->GetMembers()) {
                Log(LogNotice, "ExternalCommandProcessor")
                    << "Creating downtime for service " << service->GetName();
-               (void) service->AddDowntime(arguments[6], arguments[7],
+               (void) Downtime::AddDowntime(service, arguments[6], arguments[7],
                    Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
                    Convert::ToBool(is_fixed), triggeredBy, Convert::ToDouble(arguments[5]));
        }
@@ -1184,7 +1172,7 @@ void ExternalCommandProcessor::AddHostComment(double, const std::vector<String>&
 
        Log(LogNotice, "ExternalCommandProcessor")
            << "Creating comment for host " << host->GetName();
-       (void) host->AddComment(CommentUser, arguments[2], arguments[3], 0);
+       (void) Comment::AddComment(host, CommentUser, arguments[2], arguments[3], 0);
 }
 
 void ExternalCommandProcessor::DelHostComment(double, const std::vector<String>& arguments)
@@ -1192,8 +1180,8 @@ void ExternalCommandProcessor::DelHostComment(double, const std::vector<String>&
        int id = Convert::ToLong(arguments[0]);
        Log(LogNotice, "ExternalCommandProcessor")
            << "Removing comment ID " << arguments[0];
-       String rid = Service::GetCommentIDFromLegacyID(id);
-       Service::RemoveComment(rid);
+       String rid = Comment::GetCommentIDFromLegacyID(id);
+       Comment::RemoveComment(rid);
 }
 
 void ExternalCommandProcessor::AddSvcComment(double, const std::vector<String>& arguments)
@@ -1205,7 +1193,7 @@ void ExternalCommandProcessor::AddSvcComment(double, const std::vector<String>&
 
        Log(LogNotice, "ExternalCommandProcessor")
            << "Creating comment for service " << service->GetName();
-       (void) service->AddComment(CommentUser, arguments[3], arguments[4], 0);
+       (void) Comment::AddComment(service, CommentUser, arguments[3], arguments[4], 0);
 }
 
 void ExternalCommandProcessor::DelSvcComment(double, const std::vector<String>& arguments)
@@ -1214,8 +1202,8 @@ void ExternalCommandProcessor::DelSvcComment(double, const std::vector<String>&
        Log(LogNotice, "ExternalCommandProcessor")
            << "Removing comment ID " << arguments[0];
 
-       String rid = Service::GetCommentIDFromLegacyID(id);
-       Service::RemoveComment(rid);
+       String rid = Comment::GetCommentIDFromLegacyID(id);
+       Comment::RemoveComment(rid);
 }
 
 void ExternalCommandProcessor::DelAllHostComments(double, const std::vector<String>& arguments)
index 8b7dd25a06066f3f548f7c436e2029b6af14b5b1..7cecf285a2a5e107569f156a413f3f86656d4c80 100644 (file)
@@ -71,9 +71,9 @@ void Host::CreateChildObjects(const Type::Ptr& childType)
                Service::EvaluateApplyRules(this);
 }
 
-void Host::Stop(void)
+void Host::Stop(bool runtimeRemoved)
 {
-       ObjectImpl<Host>::Stop();
+       ObjectImpl<Host>::Stop(runtimeRemoved);
 
        Array::Ptr groups = GetGroups();
 
index 8f64a52c7824fac1acb256360f7ec78980246cf9..8afa9dae5a6b33c481f6c58363e813b11266c13f 100644 (file)
@@ -66,7 +66,7 @@ public:
        virtual bool ResolveMacro(const String& macro, const CheckResult::Ptr& cr, Value *result) const override;
 
 protected:
-       virtual void Stop(void) override;
+       virtual void Stop(bool runtimeRemoved) override;
 
        virtual void OnAllConfigLoaded(void) override;
        virtual void CreateChildObjects(const Type::Ptr& childType) override;
index d9be27dfcca79d2f75fa49f5fad604b77730ab58..069dab85209e035ff9fa0af8d6df500f8fdc6b78 100644 (file)
@@ -56,9 +56,9 @@ void IcingaStatusWriter::StatsFunc(const Dictionary::Ptr& status, const Array::P
 /**
  * Starts the component.
  */
-void IcingaStatusWriter::Start(void)
+void IcingaStatusWriter::Start(bool runtimeCreated)
 {
-       ObjectImpl<IcingaStatusWriter>::Start();
+       ObjectImpl<IcingaStatusWriter>::Start(runtimeCreated);
 
        /* TODO: remove in versions > 2.4 */
        Log(LogWarning, "IcingaStatusWriter", "This feature was deprecated in 2.4 and will be removed in future Icinga 2 releases.");
index e2a458640eaa5e245a0dd4624993f5c68b586b9d..90b1704b8db6583d5460fc47a0794600b161746e 100644 (file)
@@ -39,7 +39,7 @@ public:
        static Dictionary::Ptr GetStatusData(void);
 
 protected:
-       virtual void Start(void) override;
+       virtual void Start(bool runtimeCreated) override;
 
 private:
        Timer::Ptr m_StatusTimer;
index 5c25ffbbece5f7c2ad7bc605f9ef37cfec0c0d52..30e6cb1c9607470e1cde360db48dc042b5edccae 100644 (file)
@@ -99,48 +99,52 @@ void Notification::StaticInitialize(void)
 
 void Notification::OnConfigLoaded(void)
 {
+       ObjectImpl<Notification>::OnConfigLoaded();
+
        SetTypeFilter(FilterArrayToInt(GetTypes(), ~0));
        SetStateFilter(FilterArrayToInt(GetStates(), ~0));
 }
 
 void Notification::OnAllConfigLoaded(void)
 {
-       Checkable::Ptr obj = GetCheckable();
+       ObjectImpl<Notification>::OnAllConfigLoaded();
+
+       Host::Ptr host = Host::GetByName(GetHostName());
 
-       if (!obj)
+       if (GetServiceName().IsEmpty())
+               m_Checkable = host;
+       else
+               m_Checkable = host->GetServiceByShortName(GetServiceName());
+
+       if (!m_Checkable)
                BOOST_THROW_EXCEPTION(ScriptError("Notification object refers to a host/service which doesn't exist.", GetDebugInfo()));
 
-       obj->AddNotification(this);
+       m_Checkable->RegisterNotification(this);
 }
 
-void Notification::Start(void)
+void Notification::Start(bool runtimeCreated)
 {
-       ObjectImpl<Notification>::Start();
+       ObjectImpl<Notification>::Start(runtimeCreated);
 
        Checkable::Ptr obj = GetCheckable();
 
        if (obj)
-               obj->AddNotification(this);
+               obj->RegisterNotification(this);
 }
 
-void Notification::Stop(void)
+void Notification::Stop(bool runtimeRemoved)
 {
-       ObjectImpl<Notification>::Stop();
+       ObjectImpl<Notification>::Stop(runtimeRemoved);
 
        Checkable::Ptr obj = GetCheckable();
 
        if (obj)
-               obj->RemoveNotification(this);
+               obj->UnregisterNotification(this);
 }
 
 Checkable::Ptr Notification::GetCheckable(void) const
 {
-       Host::Ptr host = Host::GetByName(GetHostName());
-
-       if (GetServiceName().IsEmpty())
-               return host;
-       else
-               return host->GetServiceByShortName(GetServiceName());
+       return m_Checkable;
 }
 
 NotificationCommand::Ptr Notification::GetCommand(void) const
index 4fa7538d82458042b8854a36e3ca8f08865c4dd0..6286fe8840ef266fe1b370f42b9581d1938a3037 100644 (file)
@@ -118,10 +118,12 @@ public:
 protected:
        virtual void OnConfigLoaded(void) override;
        virtual void OnAllConfigLoaded(void) override;
-       virtual void Start(void) override;
-       virtual void Stop(void) override;
+       virtual void Start(bool runtimeCreated) override;
+       virtual void Stop(bool runtimeRemoved) override;
 
 private:
+       intrusive_ptr<Checkable> m_Checkable;
+
        void ExecuteNotificationHelper(NotificationType type, const User::Ptr& user, const CheckResult::Ptr& cr, bool force, const String& author = "", const String& text = "");
 
        static bool EvaluateApplyRuleInstance(const intrusive_ptr<Checkable>& checkable, const String& name, ScriptFrame& frame, const ApplyRule& rule);
index 763e9fa7e33ffba3028d84af038f62fc20a14074..d03734a546895a84e2f929ff160f928d9d7e19c8 100644 (file)
@@ -96,11 +96,11 @@ void ScheduledDowntime::OnAllConfigLoaded(void)
                BOOST_THROW_EXCEPTION(ScriptError("ScheduledDowntime '" + GetName() + "' references a host/service which doesn't exist.", GetDebugInfo()));
 }
 
-void ScheduledDowntime::Start(void)
+void ScheduledDowntime::Start(bool runtimeCreated)
 {
-       ObjectImpl<ScheduledDowntime>::Start();
+       ObjectImpl<ScheduledDowntime>::Start(runtimeCreated);
 
-       CreateNextDowntime();
+       Utility::QueueAsyncCallback(boost::bind(&ScheduledDowntime::CreateNextDowntime, this));
 }
 
 void ScheduledDowntime::TimerProc(void)
@@ -168,20 +168,13 @@ std::pair<double, double> ScheduledDowntime::FindNextSegment(void)
 
 void ScheduledDowntime::CreateNextDowntime(void)
 {
-       Dictionary::Ptr downtimes = GetCheckable()->GetDowntimes();
-
-       {
-               ObjectLock dlock(downtimes);
-               BOOST_FOREACH(const Dictionary::Pair& kv, downtimes) {
-                       Downtime::Ptr downtime = kv.second;
-
-                       if (downtime->GetScheduledBy() != GetName() ||
-                           downtime->GetStartTime() < Utility::GetTime())
-                               continue;
+       BOOST_FOREACH(const Downtime::Ptr& downtime, GetCheckable()->GetDowntimes()) {
+               if (downtime->GetScheduledBy() != GetName() ||
+                   downtime->GetStartTime() < Utility::GetTime())
+                       continue;
 
-                       /* We've found a downtime that is owned by us and that hasn't started yet - we're done. */
-                       return;
-               }
+               /* We've found a downtime that is owned by us and that hasn't started yet - we're done. */
+               return;
        }
 
        std::pair<double, double> segment = FindNextSegment();
@@ -196,12 +189,9 @@ void ScheduledDowntime::CreateNextDowntime(void)
                return;
        }
 
-       String uid = GetCheckable()->AddDowntime(GetAuthor(), GetComment(),
+       Downtime::AddDowntime(GetCheckable(), GetAuthor(), GetComment(),
            segment.first, segment.second,
-           GetFixed(), String(), GetDuration(), GetName());
-
-       Downtime::Ptr downtime = Checkable::GetDowntimeByID(uid);
-       downtime->SetConfigOwner(GetName());
+           GetFixed(), String(), GetDuration(), GetName(), GetName());
 }
 
 void ScheduledDowntime::ValidateRanges(const Dictionary::Ptr& value, const ValidationUtils& utils)
index 592f23865fd8817844e550ad5f519fd92d9db0ea..cdca82274b0872f9dd6b8293e8669d47ae98191f 100644 (file)
@@ -57,7 +57,7 @@ public:
 
 protected:
        virtual void OnAllConfigLoaded(void) override;
-       virtual void Start(void) override;
+       virtual void Start(bool runtimeCreated) override;
 
 private:
        static void TimerProc(void);
index 651a0d3f4438e071542e56e6c92bd4668a6648c5..243eea62a479fb2bb1f4d70ceb610d32b681c2e2 100644 (file)
@@ -44,9 +44,9 @@ void TimePeriod::StaticInitialize(void)
        l_UpdateTimer->Start();
 }
 
-void TimePeriod::Start(void)
+void TimePeriod::Start(bool runtimeCreated)
 {
-       ObjectImpl<TimePeriod>::Start();
+       ObjectImpl<TimePeriod>::Start(runtimeCreated);
 
        /* Pre-fill the time period for the next 24 hours. */
        double now = Utility::GetTime();
index f7120c1f13ec70c62e6b8cf41d19b0b4ab6f4fa8..716c12cc61e084925d2e3eee10d4db57aab6d001 100644 (file)
@@ -39,7 +39,7 @@ public:
 
        static void StaticInitialize(void);
 
-       virtual void Start(void) override;
+       virtual void Start(bool runtimeCreated) override;
 
        void UpdateRegion(double begin, double end, bool clearExisting);
 
index 048109e6cedbec640c1eedbc8c2685ba6b389c9b..81795db41d9a256ba5724553fff40742074683bc 100644 (file)
@@ -60,9 +60,9 @@ void User::OnAllConfigLoaded(void)
        }
 }
 
-void User::Stop(void)
+void User::Stop(bool runtimeRemoved)
 {
-       ObjectImpl<User>::Stop();
+       ObjectImpl<User>::Stop(runtimeRemoved);
 
        Array::Ptr groups = GetGroups();
 
index e86f71e81086852f4dae529519103d72afd11abc..378fae05836be5d7dc0387903931f01a10f041f9 100644 (file)
@@ -48,7 +48,7 @@ public:
        virtual void ValidateTypes(const Array::Ptr& value, const ValidationUtils& utils) override;
 
 protected:
-       virtual void Stop(void) override;
+       virtual void Stop(bool runtimeRemoved) override;
 
        virtual void OnConfigLoaded(void) override;
        virtual void OnAllConfigLoaded(void) override;
index c182c84d4e886aa3eab0a579d0c20135c9342a76..283b2aa80a560259f931b816bfdab88ec6b47584 100644 (file)
@@ -65,34 +65,9 @@ String CommentsTable::GetPrefix(void) const
 
 void CommentsTable::FetchRows(const AddRowFunction& addRowFn)
 {
-       BOOST_FOREACH(const Host::Ptr& host, ConfigType::GetObjectsByType<Host>()) {
-               Dictionary::Ptr comments = host->GetComments();
-
-               ObjectLock olock(comments);
-
-               String id;
-               Comment::Ptr comment;
-               BOOST_FOREACH(tie(id, comment), comments) {
-                       if (Host::GetOwnerByCommentID(id) == host) {
-                               if (!addRowFn(comment, LivestatusGroupByNone, Empty))
-                                       return;
-                       }
-               }
-       }
-
-       BOOST_FOREACH(const Service::Ptr& service, ConfigType::GetObjectsByType<Service>()) {
-               Dictionary::Ptr comments = service->GetComments();
-
-               ObjectLock olock(comments);
-
-               String id;
-               Comment::Ptr comment;
-               BOOST_FOREACH(tie(id, comment), comments) {
-                       if (Service::GetOwnerByCommentID(id) == service) {
-                               if (!addRowFn(comment, LivestatusGroupByNone, Empty))
-                                       return;
-                       }
-               }
+       BOOST_FOREACH(const Comment::Ptr& comment, ConfigType::GetObjectsByType<Comment>()) {
+               if (!addRowFn(comment, LivestatusGroupByNone, Empty))
+                       return;
        }
 }
 
@@ -100,7 +75,7 @@ Object::Ptr CommentsTable::HostAccessor(const Value& row, const Column::ObjectAc
 {
        Comment::Ptr comment = static_cast<Comment::Ptr>(row);
 
-       Checkable::Ptr checkable = Checkable::GetOwnerByCommentID(comment->GetId());
+       Checkable::Ptr checkable = comment->GetCheckable();
 
        Host::Ptr host;
        Service::Ptr service;
@@ -113,7 +88,7 @@ Object::Ptr CommentsTable::ServiceAccessor(const Value& row, const Column::Objec
 {
        Comment::Ptr comment = static_cast<Comment::Ptr>(row);
 
-       Checkable::Ptr checkable = Checkable::GetOwnerByCommentID(comment->GetId());
+       Checkable::Ptr checkable = comment->GetCheckable();
 
        Host::Ptr host;
        Service::Ptr service;
@@ -165,7 +140,7 @@ Value CommentsTable::EntryTimeAccessor(const Value& row)
 Value CommentsTable::TypeAccessor(const Value& row)
 {
        Comment::Ptr comment = static_cast<Comment::Ptr>(row);
-       Checkable::Ptr checkable = Checkable::GetOwnerByCommentID(comment->GetId());
+       Checkable::Ptr checkable = comment->GetCheckable();
 
        if (!checkable)
                return Empty;
@@ -179,7 +154,7 @@ Value CommentsTable::TypeAccessor(const Value& row)
 Value CommentsTable::IsServiceAccessor(const Value& row)
 {
        Comment::Ptr comment = static_cast<Comment::Ptr>(row);
-       Checkable::Ptr checkable = Checkable::GetOwnerByCommentID(comment->GetId());
+       Checkable::Ptr checkable = comment->GetCheckable();
 
        if (!checkable)
                return Empty;
index 0bfc301e9656f19a7ac2926eaa83407318a94108..a081c22b2c8f5847b5fd4a215140be39186e9405 100644 (file)
@@ -65,34 +65,9 @@ String DowntimesTable::GetPrefix(void) const
 
 void DowntimesTable::FetchRows(const AddRowFunction& addRowFn)
 {
-       BOOST_FOREACH(const Host::Ptr& host, ConfigType::GetObjectsByType<Host>()) {
-               Dictionary::Ptr downtimes = host->GetDowntimes();
-
-               ObjectLock olock(downtimes);
-
-               String id;
-               Downtime::Ptr downtime;
-               BOOST_FOREACH(boost::tie(id, downtime), downtimes) {
-                       if (Host::GetOwnerByDowntimeID(id) == host) {
-                               if (!addRowFn(downtime, LivestatusGroupByNone, Empty))
-                                       return;
-                       }
-               }
-       }
-
-       BOOST_FOREACH(const Service::Ptr& service, ConfigType::GetObjectsByType<Service>()) {
-               Dictionary::Ptr downtimes = service->GetDowntimes();
-
-               ObjectLock olock(downtimes);
-
-               String id;
-               Downtime::Ptr downtime;
-               BOOST_FOREACH(boost::tie(id, downtime), downtimes) {
-                       if (Service::GetOwnerByDowntimeID(id) == service) {
-                               if (!addRowFn(downtime, LivestatusGroupByNone, Empty))
-                                       return;
-                       }
-               }
+       BOOST_FOREACH(const Downtime::Ptr& downtime, ConfigType::GetObjectsByType<Downtime>()) {
+               if (!addRowFn(downtime, LivestatusGroupByNone, Empty))
+                       return;
        }
 }
 
@@ -100,7 +75,7 @@ Object::Ptr DowntimesTable::HostAccessor(const Value& row, const Column::ObjectA
 {
        Downtime::Ptr downtime = static_cast<Downtime::Ptr>(row);
 
-       Checkable::Ptr checkable = Checkable::GetOwnerByDowntimeID(downtime->GetId());
+       Checkable::Ptr checkable = downtime->GetCheckable();
 
        Host::Ptr host;
        Service::Ptr service;
@@ -113,7 +88,7 @@ Object::Ptr DowntimesTable::ServiceAccessor(const Value& row, const Column::Obje
 {
        Downtime::Ptr downtime = static_cast<Downtime::Ptr>(row);
 
-       Checkable::Ptr checkable = Checkable::GetOwnerByDowntimeID(downtime->GetId());
+       Checkable::Ptr checkable = downtime->GetCheckable();
 
        Host::Ptr host;
        Service::Ptr service;
@@ -160,7 +135,7 @@ Value DowntimesTable::TypeAccessor(const Value& row)
 Value DowntimesTable::IsServiceAccessor(const Value& row)
 {
        Downtime::Ptr downtime = static_cast<Downtime::Ptr>(row);
-       Checkable::Ptr checkable = Checkable::GetOwnerByDowntimeID(downtime->GetId());
+       Checkable::Ptr checkable = downtime->GetCheckable();
 
        return (dynamic_pointer_cast<Host>(checkable) ? 0 : 1);
 }
@@ -197,5 +172,12 @@ Value DowntimesTable::TriggeredByAccessor(const Value& row)
 {
        Downtime::Ptr downtime = static_cast<Downtime::Ptr>(row);
 
-       return downtime->GetTriggeredByLegacyId();
+       String triggerDowntimeName = downtime->GetTriggeredBy();
+
+       Downtime::Ptr triggerDowntime = Downtime::GetByName(triggerDowntimeName);
+
+       if (triggerDowntime)
+               return triggerDowntime->GetLegacyId();
+
+       return Empty;
 }
index 50bb95b31f867b868c91745f8cc59463992aba0f..38e4c97afc85ca4442e19eb8d429c8a5dde15ea9 100644 (file)
@@ -902,26 +902,16 @@ Value HostsTable::DowntimesAccessor(const Value& row)
        if (!host)
                return Empty;
 
-       Dictionary::Ptr downtimes = host->GetDowntimes();
-
-       Array::Ptr ids = new Array();
-
-       ObjectLock olock(downtimes);
-
-       String id;
-       Downtime::Ptr downtime;
-       BOOST_FOREACH(tie(id, downtime), downtimes) {
-
-               if (!downtime)
-                       continue;
+       Array::Ptr results = new Array();
 
+       BOOST_FOREACH(const Downtime::Ptr& downtime, host->GetDowntimes()) {
                if (downtime->IsExpired())
                        continue;
 
-               ids->Add(downtime->GetLegacyId());
+               results->Add(downtime->GetLegacyId());
        }
 
-       return ids;
+       return results;
 }
 
 Value HostsTable::DowntimesWithInfoAccessor(const Value& row)
@@ -931,19 +921,9 @@ Value HostsTable::DowntimesWithInfoAccessor(const Value& row)
        if (!host)
                return Empty;
 
-       Dictionary::Ptr downtimes = host->GetDowntimes();
-
-       Array::Ptr ids = new Array();
-
-       ObjectLock olock(downtimes);
-
-       String id;
-       Downtime::Ptr downtime;
-       BOOST_FOREACH(tie(id, downtime), downtimes) {
-
-               if (!downtime)
-                       continue;
+       Array::Ptr results = new Array();
 
+       BOOST_FOREACH(const Downtime::Ptr& downtime, host->GetDowntimes()) {
                if (downtime->IsExpired())
                        continue;
 
@@ -951,10 +931,10 @@ Value HostsTable::DowntimesWithInfoAccessor(const Value& row)
                downtime_info->Add(downtime->GetLegacyId());
                downtime_info->Add(downtime->GetAuthor());
                downtime_info->Add(downtime->GetComment());
-               ids->Add(downtime_info);
+               results->Add(downtime_info);
        }
 
-       return ids;
+       return results;
 }
 
 Value HostsTable::CommentsAccessor(const Value& row)
@@ -964,26 +944,15 @@ Value HostsTable::CommentsAccessor(const Value& row)
        if (!host)
                return Empty;
 
-       Dictionary::Ptr comments = host->GetComments();
-
-       Array::Ptr ids = new Array();
-
-       ObjectLock olock(comments);
-
-       String id;
-       Comment::Ptr comment;
-       BOOST_FOREACH(tie(id, comment), comments) {
-
-               if (!comment)
-                       continue;
-
+       Array::Ptr results = new Array();
+       BOOST_FOREACH(const Comment::Ptr& comment, host->GetComments()) {
                if (comment->IsExpired())
                        continue;
 
-               ids->Add(comment->GetLegacyId());
+               results->Add(comment->GetLegacyId());
        }
 
-       return ids;
+       return results;
 }
 
 Value HostsTable::CommentsWithInfoAccessor(const Value& row)
@@ -993,19 +962,9 @@ Value HostsTable::CommentsWithInfoAccessor(const Value& row)
        if (!host)
                return Empty;
 
-       Dictionary::Ptr comments = host->GetComments();
-
-       Array::Ptr ids = new Array();
-
-       ObjectLock olock(comments);
-
-       String id;
-       Comment::Ptr comment;
-       BOOST_FOREACH(tie(id, comment), comments) {
-
-               if (!comment)
-                       continue;
+       Array::Ptr results = new Array();
 
+       BOOST_FOREACH(const Comment::Ptr& comment, host->GetComments()) {
                if (comment->IsExpired())
                        continue;
 
@@ -1013,10 +972,10 @@ Value HostsTable::CommentsWithInfoAccessor(const Value& row)
                comment_info->Add(comment->GetLegacyId());
                comment_info->Add(comment->GetAuthor());
                comment_info->Add(comment->GetText());
-               ids->Add(comment_info);
+               results->Add(comment_info);
        }
 
-       return ids;
+       return results;
 }
 
 Value HostsTable::CommentsWithExtraInfoAccessor(const Value& row)
@@ -1026,19 +985,9 @@ Value HostsTable::CommentsWithExtraInfoAccessor(const Value& row)
        if (!host)
                return Empty;
 
-       Dictionary::Ptr comments = host->GetComments();
-
-       Array::Ptr ids = new Array();
-
-       ObjectLock olock(comments);
-
-       String id;
-       Comment::Ptr comment;
-       BOOST_FOREACH(tie(id, comment), comments) {
-
-               if (!comment)
-                       continue;
+       Array::Ptr results = new Array();
 
+       BOOST_FOREACH(const Comment::Ptr& comment, host->GetComments()) {
                if (comment->IsExpired())
                        continue;
 
@@ -1048,10 +997,10 @@ Value HostsTable::CommentsWithExtraInfoAccessor(const Value& row)
                comment_info->Add(comment->GetText());
                comment_info->Add(comment->GetEntryType());
                comment_info->Add(static_cast<int>(comment->GetEntryTime()));
-               ids->Add(comment_info);
+               results->Add(comment_info);
        }
 
-       return ids;
+       return results;
 }
 
 Value HostsTable::CustomVariableNamesAccessor(const Value& row)
index b12a6b0767b69e23e6ef526d52e080707e302ac1..67547e56154436e6a2c8613e76f8bb4c41e96768 100644 (file)
@@ -62,9 +62,9 @@ void LivestatusListener::StatsFunc(const Dictionary::Ptr& status, const Array::P
 /**
  * Starts the component.
  */
-void LivestatusListener::Start(void)
+void LivestatusListener::Start(bool runtimeCreated)
 {
-       ObjectImpl<LivestatusListener>::Start();
+       ObjectImpl<LivestatusListener>::Start(runtimeCreated);
 
        if (GetSocketType() == "tcp") {
                TcpSocket::Ptr socket = new TcpSocket();
@@ -119,9 +119,9 @@ void LivestatusListener::Start(void)
        }
 }
 
-void LivestatusListener::Stop(void)
+void LivestatusListener::Stop(bool runtimeRemoved)
 {
-       ObjectImpl<LivestatusListener>::Stop();
+       ObjectImpl<LivestatusListener>::Stop(runtimeRemoved);
 
        m_Listener->Close();
 
index f0b1f12b5d3a965befa4fe9022a9ee692871d134..21a5e390ffcde3ec960dcf8dc0e3fe2775bc0afa 100644 (file)
@@ -48,8 +48,8 @@ public:
        virtual void ValidateSocketType(const String& value, const ValidationUtils& utils) override;
 
 protected:
-       virtual void Start(void) override;
-       virtual void Stop(void) override;
+       virtual void Start(bool runtimeCreated) override;
+       virtual void Stop(bool runtimeRemoved) override;
 
 private:
        void ServerThreadProc(void);
index 2043dda48593a06c6ee6a4c974bb2648ae3d9b5f..291c6eed673aa9dde17212e1b1b38b4d04afd48e 100644 (file)
@@ -940,26 +940,16 @@ Value ServicesTable::DowntimesAccessor(const Value& row)
        if (!service)
                return Empty;
 
-       Dictionary::Ptr downtimes = service->GetDowntimes();
-
-       Array::Ptr ids = new Array();
-
-       ObjectLock olock(downtimes);
-
-       String id;
-       Downtime::Ptr downtime;
-       BOOST_FOREACH(tie(id, downtime), downtimes) {
-
-               if (!downtime)
-                       continue;
+       Array::Ptr results = new Array();
 
+       BOOST_FOREACH(const Downtime::Ptr& downtime, service->GetDowntimes()) {
                if (downtime->IsExpired())
                        continue;
 
-               ids->Add(downtime->GetLegacyId());
+               results->Add(downtime->GetLegacyId());
        }
 
-       return ids;
+       return results;
 }
 
 Value ServicesTable::DowntimesWithInfoAccessor(const Value& row)
@@ -969,19 +959,9 @@ Value ServicesTable::DowntimesWithInfoAccessor(const Value& row)
        if (!service)
                return Empty;
 
-       Dictionary::Ptr downtimes = service->GetDowntimes();
-
-       Array::Ptr ids = new Array();
-
-       ObjectLock olock(downtimes);
-
-       String id;
-       Downtime::Ptr downtime;
-       BOOST_FOREACH(tie(id, downtime), downtimes) {
-
-               if (!downtime)
-                       continue;
+       Array::Ptr results = new Array();
 
+       BOOST_FOREACH(const Downtime::Ptr& downtime, service->GetDowntimes()) {
                if (downtime->IsExpired())
                        continue;
 
@@ -989,10 +969,10 @@ Value ServicesTable::DowntimesWithInfoAccessor(const Value& row)
                downtime_info->Add(downtime->GetLegacyId());
                downtime_info->Add(downtime->GetAuthor());
                downtime_info->Add(downtime->GetComment());
-               ids->Add(downtime_info);
+               results->Add(downtime_info);
        }
 
-       return ids;
+       return results;
 }
 
 Value ServicesTable::CommentsAccessor(const Value& row)
@@ -1002,26 +982,16 @@ Value ServicesTable::CommentsAccessor(const Value& row)
        if (!service)
                return Empty;
 
-       Dictionary::Ptr comments = service->GetComments();
-
-       Array::Ptr ids = new Array();
-
-       ObjectLock olock(comments);
-
-       String id;
-       Comment::Ptr comment;
-       BOOST_FOREACH(tie(id, comment), comments) {
-
-               if (!comment)
-                       continue;
+       Array::Ptr results = new Array();
 
+       BOOST_FOREACH(const Comment::Ptr& comment, service->GetComments()) {
                if (comment->IsExpired())
                        continue;
 
-               ids->Add(comment->GetLegacyId());
+               results->Add(comment->GetLegacyId());
        }
 
-       return ids;
+       return results;
 }
 
 Value ServicesTable::CommentsWithInfoAccessor(const Value& row)
@@ -1031,19 +1001,9 @@ Value ServicesTable::CommentsWithInfoAccessor(const Value& row)
        if (!service)
                return Empty;
 
-       Dictionary::Ptr comments = service->GetComments();
-
-       Array::Ptr ids = new Array();
-
-       ObjectLock olock(comments);
-
-       String id;
-       Comment::Ptr comment;
-       BOOST_FOREACH(tie(id, comment), comments) {
-
-               if (!comment)
-                       continue;
+       Array::Ptr results = new Array();
 
+       BOOST_FOREACH(const Comment::Ptr& comment, service->GetComments()) {
                if (comment->IsExpired())
                        continue;
 
@@ -1051,10 +1011,10 @@ Value ServicesTable::CommentsWithInfoAccessor(const Value& row)
                comment_info->Add(comment->GetLegacyId());
                comment_info->Add(comment->GetAuthor());
                comment_info->Add(comment->GetText());
-               ids->Add(comment_info);
+               results->Add(comment_info);
        }
 
-       return ids;
+       return results;
 }
 
 Value ServicesTable::CommentsWithExtraInfoAccessor(const Value& row)
@@ -1064,19 +1024,9 @@ Value ServicesTable::CommentsWithExtraInfoAccessor(const Value& row)
        if (!service)
                return Empty;
 
-       Dictionary::Ptr comments = service->GetComments();
-
-       Array::Ptr ids = new Array();
-
-       ObjectLock olock(comments);
-
-       String id;
-       Comment::Ptr comment;
-       BOOST_FOREACH(tie(id, comment), comments) {
-
-               if (!comment)
-                       continue;
+       Array::Ptr results = new Array();
 
+       BOOST_FOREACH(const Comment::Ptr& comment, service->GetComments()) {
                if (comment->IsExpired())
                        continue;
 
@@ -1086,10 +1036,10 @@ Value ServicesTable::CommentsWithExtraInfoAccessor(const Value& row)
                comment_info->Add(comment->GetText());
                comment_info->Add(comment->GetEntryType());
                comment_info->Add(static_cast<int>(comment->GetEntryTime()));
-               ids->Add(comment_info);
+               results->Add(comment_info);
        }
 
-       return ids;
+       return results;
 }
 
 Value ServicesTable::CustomVariableNamesAccessor(const Value& row)
index 9660bfca1b335a9ff8961a38692a131af460a356..1139faa80468de5fa5957262e6a16ee9aa1d5294 100644 (file)
@@ -49,9 +49,9 @@ void NotificationComponent::StatsFunc(const Dictionary::Ptr& status, const Array
 /**
  * Starts the component.
  */
-void NotificationComponent::Start(void)
+void NotificationComponent::Start(bool runtimeCreated)
 {
-       ObjectImpl<NotificationComponent>::Start();
+       ObjectImpl<NotificationComponent>::Start(runtimeCreated);
 
        Checkable::OnNotificationsRequested.connect(boost::bind(&NotificationComponent::SendNotificationsHandler, this, _1,
            _2, _3, _4, _5));
index bc1dc1d9a0a89271efbffc929761c303a921d745..7811682861f49fe38f4262d2a61f5377ca8752db 100644 (file)
@@ -39,7 +39,7 @@ public:
 
        static void StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata);
 
-       virtual void Start(void) override;
+       virtual void Start(bool runtimeCreated) override;
 
 private:
        Timer::Ptr m_NotificationTimer;
index f3a2940ed1fbc64a800da6241ce26bff39e1c9f6..d883fe51c2dca4764f1bff2a2a828621ad2d82f4 100644 (file)
@@ -38,9 +38,9 @@ using namespace icinga;
 
 REGISTER_TYPE(GelfWriter);
 
-void GelfWriter::Start(void)
+void GelfWriter::Start(bool runtimeCreated)
 {
-       ObjectImpl<GelfWriter>::Start();
+       ObjectImpl<GelfWriter>::Start(runtimeCreated);
 
        m_ReconnectTimer = new Timer();
        m_ReconnectTimer->SetInterval(10);
index 78af64d7e828be66f0e843fd0fd3cf9e37b9c0ef..7bbf7dab4ea82d8150f0ce50951c5f4f2401c15d 100644 (file)
@@ -42,7 +42,7 @@ public:
        DECLARE_OBJECTNAME(GelfWriter);
 
 protected:
-       virtual void Start(void) override;
+       virtual void Start(bool runtimeCreated) override;
 
 private:
        Stream::Ptr m_Stream;
index 3e7640e5d4fb2038b4eff1abbf1d49f3fb6608bf..7602600a56be18dd3843c1ffda0d511d03610bfc 100644 (file)
@@ -58,9 +58,9 @@ void GraphiteWriter::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&)
        status->Set("graphitewriter", nodes);
 }
 
-void GraphiteWriter::Start(void)
+void GraphiteWriter::Start(bool runtimeCreated)
 {
-       ObjectImpl<GraphiteWriter>::Start();
+       ObjectImpl<GraphiteWriter>::Start(runtimeCreated);
 
        m_ReconnectTimer = new Timer();
        m_ReconnectTimer->SetInterval(10);
index e3dd6eede42826afdad0ec966eba640c4c96d415..0c6072428d8db0f7202e6790ae393d7ffd100bff 100644 (file)
@@ -47,7 +47,7 @@ public:
        virtual void ValidateServiceNameTemplate(const String& value, const ValidationUtils& utils) override;
 
 protected:
-       virtual void Start(void) override;
+       virtual void Start(bool runtimeCreated) override;
 
 private:
        Stream::Ptr m_Stream;
index 84607ab01374024aa0a081b6526e6420128b83d5..24557f34fea3745bd7d37a13ad4ac185ad885a78 100644 (file)
@@ -58,9 +58,9 @@ void OpenTsdbWriter::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&)
        status->Set("opentsdbwriter", nodes);
 }
 
-void OpenTsdbWriter::Start(void)
+void OpenTsdbWriter::Start(bool runtimeCreated)
 {
-       ObjectImpl<OpenTsdbWriter>::Start();
+       ObjectImpl<OpenTsdbWriter>::Start(runtimeCreated);
 
        m_ReconnectTimer = new Timer();
        m_ReconnectTimer->SetInterval(10);
index 2ef0ef0e925a4f56481b7e22ce9d4d11a0418438..e1787ab50148a0bfabc886193bb1c4a125856656 100644 (file)
@@ -44,7 +44,7 @@ public:
        static void StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata);
 
 protected:
-       virtual void Start(void) override;
+       virtual void Start(bool runtimeCreated) override;
 
 private:
        Stream::Ptr m_Stream;
index 257b0e9599c81e92b116281769c21beb08becc30..e2ca0d9cea60301d8ff06ee5e5faefd8b309d4ee 100644 (file)
@@ -49,9 +49,9 @@ void PerfdataWriter::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&)
        status->Set("perfdatawriter", nodes);
 }
 
-void PerfdataWriter::Start(void)
+void PerfdataWriter::Start(bool runtimeCreated)
 {
-       ObjectImpl<PerfdataWriter>::Start();
+       ObjectImpl<PerfdataWriter>::Start(runtimeCreated);
 
        Checkable::OnNewCheckResult.connect(boost::bind(&PerfdataWriter::CheckResultHandler, this, _1, _2));
 
index 12999c40600ec229d9dbfa1ff9184e3543d6418e..aac43fe699f7b51cf25e5dcaf8b7540fa3af92c3 100644 (file)
@@ -46,7 +46,7 @@ public:
        virtual void ValidateServiceFormatTemplate(const String& value, const ValidationUtils& utils) override;
 
 protected:
-       virtual void Start(void) override;
+       virtual void Start(bool runtimeCreated) override;
 
 private:
        void CheckResultHandler(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr);
index 1e93632b104f0960dba5cac9de3802d7e58bb4ef..653b7364b1f7ab5912a8fb4c2f40defc2253a4ce 100644 (file)
@@ -97,7 +97,7 @@ void ApiListener::OnAllConfigLoaded(void)
 /**
  * Starts the component.
  */
-void ApiListener::Start(void)
+void ApiListener::Start(bool runtimeCreated)
 {
        SyncZoneDirs();
 
@@ -107,7 +107,7 @@ void ApiListener::Start(void)
                return;
        }
 
-       ObjectImpl<ApiListener>::Start();
+       ObjectImpl<ApiListener>::Start(runtimeCreated);
 
        {
                boost::mutex::scoped_lock(m_LogLock);
index 203cdadc5181640bd31943bf8c378cb13b9758d4..9cf8278f35f04d4ddd4820f6574c4beac2563360 100644 (file)
@@ -89,7 +89,7 @@ public:
 protected:
        virtual void OnConfigLoaded(void) override;
        virtual void OnAllConfigLoaded(void) override;
-       virtual void Start(void) override;
+       virtual void Start(bool runtimeCreated) override;
 
 private:
        boost::shared_ptr<SSL_CTX> m_SSLContext;
index 3254514036b34f9b4bbfc81a678972b1a0edea49..a114ef52c664f8dcab0872081a9bfa541cb12058 100644 (file)
@@ -52,7 +52,7 @@ String ConfigObjectUtility::EscapeName(const String& name)
 }
 
 String ConfigObjectUtility::CreateObjectConfig(const Type::Ptr& type, const String& fullName,
-    const Array::Ptr& templates, const Dictionary::Ptr& attrs)
+    bool ignoreOnError, const Array::Ptr& templates, const Dictionary::Ptr& attrs)
 {
        NameComposer *nc = dynamic_cast<NameComposer *>(type.get());
        Dictionary::Ptr nameParts;
@@ -78,7 +78,7 @@ String ConfigObjectUtility::CreateObjectConfig(const Type::Ptr& type, const Stri
        allAttrs->Set("version", Utility::GetTime());
 
        std::ostringstream config;
-       ConfigWriter::EmitConfigItem(config, type->GetName(), name, false, templates, allAttrs);
+       ConfigWriter::EmitConfigItem(config, type->GetName(), name, false, ignoreOnError, templates, allAttrs);
        ConfigWriter::EmitRaw(config, "\n");
 
        return config.str();
@@ -111,7 +111,7 @@ bool ConfigObjectUtility::CreateObject(const Type::Ptr& type, const String& full
 
                WorkQueue upq;
 
-               if (!ConfigItem::CommitItems(upq) || !ConfigItem::ActivateItems(upq, false)) {
+               if (!ConfigItem::CommitItems(upq) || !ConfigItem::ActivateItems(upq, false, true)) {
                        if (errors) {
                                BOOST_FOREACH(const boost::exception_ptr& ex, upq.GetExceptions()) {
                                        errors->Add(DiagnosticInformation(ex));
@@ -161,7 +161,7 @@ bool ConfigObjectUtility::DeleteObjectHelper(const ConfigObject::Ptr& object, bo
                /* mark this object for cluster delete event */
                object->SetExtension("ConfigObjectDeleted", true);
                /* triggers signal for DB IDO and other interfaces */
-               object->Deactivate();
+               object->Deactivate(true);
 
                if (item)
                        item->Unregister();
index a8ff679222541c56c6e1be3267b33e7f086d0962..8e310fa4f78dc680972b4cc5e7b1f05ff969c4f3 100644 (file)
@@ -40,15 +40,15 @@ class I2_REMOTE_API ConfigObjectUtility
 public:
        static String GetConfigDir(void);
        static String GetObjectConfigPath(const Type::Ptr& type, const String& fullName);
-       
+
        static String CreateObjectConfig(const Type::Ptr& type, const String& fullName,
-            const Array::Ptr& templates, const Dictionary::Ptr& attrs);
-            
+            bool ignoreOnError, const Array::Ptr& templates, const Dictionary::Ptr& attrs);
+
        static bool CreateObject(const Type::Ptr& type, const String& fullName,
             const String& config, const Array::Ptr& errors);
-           
+
        static bool DeleteObject(const ConfigObject::Ptr& object, bool cascade, const Array::Ptr& errors);
-       
+
 private:
        static String EscapeName(const String& name);
        static bool DeleteObjectHelper(const ConfigObject::Ptr& object, bool cascade, const Array::Ptr& errors);
index b73b5f317ee651f24d987c165bf33ab6de59204a..a7d6ec760caedc2ad5bb635ae386136ab2f048a9 100644 (file)
@@ -22,6 +22,7 @@
 #include "remote/httputility.hpp"
 #include "remote/filterutility.hpp"
 #include "remote/apiaction.hpp"
+#include "base/configtype.hpp"
 #include <boost/algorithm/string.hpp>
 #include <set>
 
@@ -56,7 +57,12 @@ bool CreateObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r
        String status;
        Array::Ptr errors = new Array();
 
-       String config = ConfigObjectUtility::CreateObjectConfig(type, name, templates, attrs);
+       bool ignoreOnError = false;
+
+       if (params->Contains("ignore_on_error"))
+               ignoreOnError = HttpUtility::GetLastParameter(params, "ignore_on_error");
+
+       String config = ConfigObjectUtility::CreateObjectConfig(type, name, ignoreOnError, templates, attrs);
 
        if (!ConfigObjectUtility::CreateObject(type, name, config, errors)) {
                result1->Set("errors", errors);
@@ -64,8 +70,16 @@ bool CreateObjectHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& r
                return true;
        }
 
+       ConfigType::Ptr dtype = ConfigType::GetByName(type->GetName());
+
+       ConfigObject::Ptr obj = dtype->GetObject(name);
+
        result1->Set("code", 200);
-       result1->Set("status", "Object was created");
+
+       if (obj)
+               result1->Set("status", "Object was created");
+       else if (!obj && ignoreOnError)
+               result1->Set("status", "Object was not created but 'ignore_on_error' was set to true");
 
        Array::Ptr results = new Array();
        results->Add(result1);
index bc16add54bb022fd8d5fbb84070c9426f64b5421..3621c5b270089d4e7895193d3b2514cc57939e0d 100644 (file)
@@ -874,12 +874,12 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
 
                /* start/stop */
                if (needs_tracking) {
-                       m_Header << "virtual void Start(void) override;" << std::endl
-                                << "virtual void Stop(void) override;" << std::endl;
+                       m_Header << "virtual void Start(bool runtimeCreated = false) override;" << std::endl
+                                << "virtual void Stop(bool runtimeRemoved = false) override;" << std::endl;
 
-                       m_Impl << "void ObjectImpl<" << klass.Name << ">::Start(void)" << std::endl
+                       m_Impl << "void ObjectImpl<" << klass.Name << ">::Start(bool runtimeCreated)" << std::endl
                               << "{" << std::endl
-                              << "\t" << klass.Parent << "::Start();" << std::endl << std::endl;
+                              << "\t" << klass.Parent << "::Start(runtimeCreated);" << std::endl << std::endl;
 
                        for (it = klass.Fields.begin(); it != klass.Fields.end(); it++) {
                                if (!(it->Type.IsName))
@@ -889,9 +889,9 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
                        }
 
                        m_Impl << "}" << std::endl << std::endl
-                              << "void ObjectImpl<" << klass.Name << ">::Stop(void)" << std::endl
+                              << "void ObjectImpl<" << klass.Name << ">::Stop(bool runtimeRemoved)" << std::endl
                               << "{" << std::endl
-                              << "\t" << klass.Parent << "::Stop();" << std::endl << std::endl;
+                              << "\t" << klass.Parent << "::Stop(runtimeRemoved);" << std::endl << std::endl;
 
                        for (it = klass.Fields.begin(); it != klass.Fields.end(); it++) {
                                if (!(it->Type.IsName))