/**
* Destructor for the application class.
*/
-void Application::Stop(void)
+void Application::Stop(bool runtimeRemoved)
{
m_ShuttingDown = true;
} else
ClosePidFile(true);
- ObjectImpl<Application>::Stop();
+ ObjectImpl<Application>::Stop(runtimeRemoved);
}
Application::~Application(void)
protected:
virtual void OnConfigLoaded(void) override;
- virtual void Stop(void) override;
+ virtual void Stop(bool runtimeRemoved) override;
void RunEventLoop(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);
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());
NotifyActive();
}
-void ConfigObject::Stop(void)
+void ConfigObject::Stop(bool runtimeRemoved)
{
- ObjectImpl<ConfigObject>::Stop();
+ ObjectImpl<ConfigObject>::Stop(runtimeRemoved);
ASSERT(!OwnsLock());
ObjectLock olock(this);
SetStopCalled(true);
}
-void ConfigObject::Deactivate(void)
+void ConfigObject::Deactivate(bool runtimeRemoved)
{
CONTEXT("Deactivating object '" + GetName() + "' of type '" + GetType()->GetName() + "'");
SetActive(false, true);
}
- Stop();
+ Stop(runtimeRemoved);
ASSERT(GetStopCalled());
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);
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:
}
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 ";
EmitIdentifier(fp, type, false);
fp << " ";
EmitString(fp, name);
+
+ if (ignoreOnError)
+ fp << " ignore_on_error";
+
fp << " ";
EmitScope(fp, 1, attrs, imports);
}
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);
/**
* Constructor for the FileLogger class.
*/
-void FileLogger::Start(void)
+void FileLogger::Start(bool runtimeCreated)
{
- ObjectImpl<FileLogger>::Start();
+ ObjectImpl<FileLogger>::Start(runtimeCreated);
ReopenLogFile();
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);
/**
* 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)
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;
: 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)
StreamLogger(void);
- virtual void Stop(void) override;
+ virtual void Stop(bool runtimeRemoved) override;
~StreamLogger(void);
void BindStream(std::ostream *stream, bool ownsStream);
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));
m_ResultTimer->Start();
}
-void CheckerComponent::Stop(void)
+void CheckerComponent::Stop(bool runtimeRemoved)
{
Log(LogInformation, "CheckerComponent", "Checker stopped.");
m_ResultTimer->Stop();
m_Thread.join();
- ObjectImpl<CheckerComponent>::Stop();
+ ObjectImpl<CheckerComponent>::Stop(runtimeRemoved);
}
void CheckerComponent::CheckThreadProc(void)
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);
/**
* @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));
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;
/**
* @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));
/**
* @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;
/**
* @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;
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);
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);
/**
* 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()));
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
/**
* Starts the component.
*/
-void StatusDataWriter::Start(void)
+void StatusDataWriter::Start(bool runtimeCreated)
{
- ObjectImpl<StatusDataWriter>::Start();
+ ObjectImpl<StatusDataWriter>::Start(runtimeCreated);
m_ObjectsCacheOutdated = true;
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;
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;
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();
"\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";
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;
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);
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;
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);
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 {
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));
}
}
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);
const String& name);
static bool CommitNewItems(WorkQueue& upq, std::vector<ConfigItem::Ptr>& newItems);
+
+ void OnAllConfigLoadedWrapper(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));
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;
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));
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));
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));
/* 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;
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 {
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;
/* 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);
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()));
void DbEvents::RemoveDowntimes(const Checkable::Ptr& checkable)
{
- Log(LogDebug, "DbEvents")
- << "removing service downtimes for '" << checkable->GetName() << "'";
-
DbQuery query1;
query1.Table = "scheduleddowntime";
query1.Type = DbQueryDelete;
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;
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);
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;
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;
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);
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);
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);
/* 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);
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);
};
/**
* 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);
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);
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);
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();
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 + "'.");
}
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();
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 + "'.");
}
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)
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");
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");
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");
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");
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");
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) {
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);
};
}
******************************************************************************/
#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);
}
#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;
}
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++;
}
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);
+}
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);
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)
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);
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);
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;
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;
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;
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);
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);
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)
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);
#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());
+ }
+}
#include "icinga/i2-icinga.hpp"
#include "icinga/comment.thpp"
+#include "remote/messageorigin.hpp"
namespace icinga
{
+class Checkable;
+
/**
- * A service comment.
+ * A comment.
*
* @ingroup icinga
*/
{
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);
};
}
* 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
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;
};
}
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);
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;
#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();
{
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."));
+}
#include "icinga/i2-icinga.hpp"
#include "icinga/downtime.thpp"
+#include "remote/messageorigin.hpp"
namespace icinga
{
+class Checkable;
+
/**
- * A service downtime.
+ * A downtime.
*
* @ingroup icinga
*/
{
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);
};
}
* 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;
};
}
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);
}
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);
}
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);
}
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);
}
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]));
}
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)
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]));
}
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)
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);
+ }
}
}
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]));
}
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]));
}
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
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]));
}
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
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]));
}
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]));
}
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)
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)
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)
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)
Service::EvaluateApplyRules(this);
}
-void Host::Stop(void)
+void Host::Stop(bool runtimeRemoved)
{
- ObjectImpl<Host>::Stop();
+ ObjectImpl<Host>::Stop(runtimeRemoved);
Array::Ptr groups = GetGroups();
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;
/**
* 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.");
static Dictionary::Ptr GetStatusData(void);
protected:
- virtual void Start(void) override;
+ virtual void Start(bool runtimeCreated) override;
private:
Timer::Ptr m_StatusTimer;
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
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);
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)
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();
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)
protected:
virtual void OnAllConfigLoaded(void) override;
- virtual void Start(void) override;
+ virtual void Start(bool runtimeCreated) override;
private:
static void TimerProc(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();
static void StaticInitialize(void);
- virtual void Start(void) override;
+ virtual void Start(bool runtimeCreated) override;
void UpdateRegion(double begin, double end, bool clearExisting);
}
}
-void User::Stop(void)
+void User::Stop(bool runtimeRemoved)
{
- ObjectImpl<User>::Stop();
+ ObjectImpl<User>::Stop(runtimeRemoved);
Array::Ptr groups = GetGroups();
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;
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;
}
}
{
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;
{
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;
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;
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;
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;
}
}
{
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;
{
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;
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);
}
{
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;
}
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)
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;
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)
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)
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;
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)
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;
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)
/**
* 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();
}
}
-void LivestatusListener::Stop(void)
+void LivestatusListener::Stop(bool runtimeRemoved)
{
- ObjectImpl<LivestatusListener>::Stop();
+ ObjectImpl<LivestatusListener>::Stop(runtimeRemoved);
m_Listener->Close();
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);
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)
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;
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)
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)
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;
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)
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;
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)
/**
* 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));
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;
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);
DECLARE_OBJECTNAME(GelfWriter);
protected:
- virtual void Start(void) override;
+ virtual void Start(bool runtimeCreated) override;
private:
Stream::Ptr m_Stream;
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);
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;
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);
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;
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));
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);
/**
* Starts the component.
*/
-void ApiListener::Start(void)
+void ApiListener::Start(bool runtimeCreated)
{
SyncZoneDirs();
return;
}
- ObjectImpl<ApiListener>::Start();
+ ObjectImpl<ApiListener>::Start(runtimeCreated);
{
boost::mutex::scoped_lock(m_LogLock);
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;
}
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;
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();
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));
/* 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();
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);
#include "remote/httputility.hpp"
#include "remote/filterutility.hpp"
#include "remote/apiaction.hpp"
+#include "base/configtype.hpp"
#include <boost/algorithm/string.hpp>
#include <set>
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);
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);
/* 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))
}
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))