Merge pull request #10397 from Icinga/activation-priority-10179

Checkable#ProcessCheckResult(): discard🗑️ CR or delay its producers shutdown
This commit is contained in:
Julian Brost 2025-05-28 12:30:40 +02:00 committed by GitHub
commit c253e7eb6e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
50 changed files with 360 additions and 214 deletions

View File

@ -87,6 +87,7 @@ set(base_SOURCES
unixsocket.cpp unixsocket.hpp unixsocket.cpp unixsocket.hpp
utility.cpp utility.hpp utility.cpp utility.hpp
value.cpp value.hpp value-operators.cpp value.cpp value.hpp value-operators.cpp
wait-group.cpp wait-group.hpp
win32.hpp win32.hpp
workqueue.cpp workqueue.hpp workqueue.cpp workqueue.hpp
) )

38
lib/base/wait-group.cpp Normal file
View File

@ -0,0 +1,38 @@
/* Icinga 2 | (c) 2025 Icinga GmbH | GPLv2+ */
#include "base/wait-group.hpp"
using namespace icinga;
bool StoppableWaitGroup::try_lock_shared()
{
std::unique_lock lock (m_Mutex);
if (m_Stopped) {
return false;
}
++m_SharedLocks;
return true;
}
void StoppableWaitGroup::unlock_shared()
{
std::unique_lock lock (m_Mutex);
if (!--m_SharedLocks && m_Stopped) {
lock.unlock();
m_CV.notify_all();
}
}
/**
* Disallow new shared locks, wait for all existing ones.
*/
void StoppableWaitGroup::Join()
{
std::unique_lock lock (m_Mutex);
m_Stopped = true;
m_CV.wait(lock, [this] { return !m_SharedLocks; });
}

54
lib/base/wait-group.hpp Normal file
View File

@ -0,0 +1,54 @@
/* Icinga 2 | (c) 2025 Icinga GmbH | GPLv2+ */
#pragma once
#include "base/object.hpp"
#include <condition_variable>
#include <cstdint>
#include <mutex>
namespace icinga
{
/**
* A synchronization interface that allows concurrent shared locking.
*
* @ingroup base
*/
class WaitGroup : public Object
{
public:
DECLARE_PTR_TYPEDEFS(WaitGroup);
virtual bool try_lock_shared() = 0;
virtual void unlock_shared() = 0;
};
/**
* A thread-safe wait group that can be stopped to prevent further shared locking.
*
* @ingroup base
*/
class StoppableWaitGroup : public WaitGroup
{
public:
DECLARE_PTR_TYPEDEFS(StoppableWaitGroup);
StoppableWaitGroup() = default;
StoppableWaitGroup(const StoppableWaitGroup&) = delete;
StoppableWaitGroup(StoppableWaitGroup&&) = delete;
StoppableWaitGroup& operator=(const StoppableWaitGroup&) = delete;
StoppableWaitGroup& operator=(StoppableWaitGroup&&) = delete;
bool try_lock_shared() override;
void unlock_shared() override;
void Join();
private:
std::mutex m_Mutex;
std::condition_variable m_CV;
uint_fast32_t m_SharedLocks = 0;
bool m_Stopped = false;
};
}

View File

@ -81,6 +81,7 @@ void CheckerComponent::Stop(bool runtimeRemoved)
m_CV.notify_all(); m_CV.notify_all();
} }
m_WaitGroup->Join();
m_ResultTimer->Stop(true); m_ResultTimer->Stop(true);
m_Thread.join(); m_Thread.join();
@ -248,7 +249,7 @@ void CheckerComponent::CheckThreadProc()
void CheckerComponent::ExecuteCheckHelper(const Checkable::Ptr& checkable) void CheckerComponent::ExecuteCheckHelper(const Checkable::Ptr& checkable)
{ {
try { try {
checkable->ExecuteCheck(); checkable->ExecuteCheck(m_WaitGroup);
} catch (const std::exception& ex) { } catch (const std::exception& ex) {
CheckResult::Ptr cr = new CheckResult(); CheckResult::Ptr cr = new CheckResult();
cr->SetState(ServiceUnknown); cr->SetState(ServiceUnknown);
@ -262,7 +263,7 @@ void CheckerComponent::ExecuteCheckHelper(const Checkable::Ptr& checkable)
cr->SetExecutionStart(now); cr->SetExecutionStart(now);
cr->SetExecutionEnd(now); cr->SetExecutionEnd(now);
checkable->ProcessCheckResult(cr); checkable->ProcessCheckResult(cr, m_WaitGroup);
Log(LogCritical, "checker", output); Log(LogCritical, "checker", output);
} }

View File

@ -8,6 +8,7 @@
#include "base/configobject.hpp" #include "base/configobject.hpp"
#include "base/timer.hpp" #include "base/timer.hpp"
#include "base/utility.hpp" #include "base/utility.hpp"
#include "base/wait-group.hpp"
#include <boost/multi_index_container.hpp> #include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp> #include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/key_extractors.hpp> #include <boost/multi_index/key_extractors.hpp>
@ -77,6 +78,7 @@ private:
CheckableSet m_IdleCheckables; CheckableSet m_IdleCheckables;
CheckableSet m_PendingCheckables; CheckableSet m_PendingCheckables;
StoppableWaitGroup::Ptr m_WaitGroup = new StoppableWaitGroup();
Timer::Ptr m_ResultTimer; Timer::Ptr m_ResultTimer;
void CheckThreadProc(); void CheckThreadProc();

View File

@ -50,6 +50,8 @@ void ExternalCommandListener::Start(bool runtimeCreated)
*/ */
void ExternalCommandListener::Stop(bool runtimeRemoved) void ExternalCommandListener::Stop(bool runtimeRemoved)
{ {
m_WaitGroup->Join();
Log(LogInformation, "ExternalCommandListener") Log(LogInformation, "ExternalCommandListener")
<< "'" << GetName() << "' stopped."; << "'" << GetName() << "' stopped.";
@ -136,7 +138,7 @@ void ExternalCommandListener::CommandPipeThread(const String& commandPath)
Log(LogInformation, "ExternalCommandListener") Log(LogInformation, "ExternalCommandListener")
<< "Executing external command: " << command; << "Executing external command: " << command;
ExternalCommandProcessor::Execute(command); ExternalCommandProcessor::Execute(m_WaitGroup, command);
} catch (const std::exception& ex) { } catch (const std::exception& ex) {
Log(LogWarning, "ExternalCommandListener") Log(LogWarning, "ExternalCommandListener")
<< "External command failed: " << DiagnosticInformation(ex, false); << "External command failed: " << DiagnosticInformation(ex, false);

View File

@ -5,6 +5,7 @@
#include "compat/externalcommandlistener-ti.hpp" #include "compat/externalcommandlistener-ti.hpp"
#include "base/objectlock.hpp" #include "base/objectlock.hpp"
#include "base/wait-group.hpp"
#include "base/timer.hpp" #include "base/timer.hpp"
#include "base/utility.hpp" #include "base/utility.hpp"
#include <thread> #include <thread>
@ -29,6 +30,8 @@ protected:
void Stop(bool runtimeRemoved) override; void Stop(bool runtimeRemoved) override;
private: private:
StoppableWaitGroup::Ptr m_WaitGroup = new StoppableWaitGroup();
#ifndef _WIN32 #ifndef _WIN32
std::thread m_CommandThread; std::thread m_CommandThread;

View File

@ -16,11 +16,11 @@
using namespace icinga; using namespace icinga;
REGISTER_FUNCTION_NONCONST(Internal, IdoCheck, &IdoCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros"); REGISTER_FUNCTION_NONCONST(Internal, IdoCheck, &IdoCheckTask::ScriptFunc, "checkable:cr:producer:resolvedMacros:useResolvedMacros");
static void ReportIdoCheck( static void ReportIdoCheck(
const Checkable::Ptr& checkable, const CheckCommand::Ptr& commandObj, const Checkable::Ptr& checkable, const CheckCommand::Ptr& commandObj, const CheckResult::Ptr& cr,
const CheckResult::Ptr& cr, String output, ServiceState state = ServiceUnknown const WaitGroup::Ptr& producer, String output, ServiceState state = ServiceUnknown
) )
{ {
if (Checkable::ExecuteCommandProcessFinishedHandler) { if (Checkable::ExecuteCommandProcessFinishedHandler) {
@ -36,12 +36,12 @@ static void ReportIdoCheck(
} else { } else {
cr->SetState(state); cr->SetState(state);
cr->SetOutput(output); cr->SetOutput(output);
checkable->ProcessCheckResult(cr); checkable->ProcessCheckResult(cr, producer);
} }
} }
void IdoCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, void IdoCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros) const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
{ {
ServiceState state; ServiceState state;
CheckCommand::Ptr commandObj = CheckCommand::ExecuteOverride ? CheckCommand::ExecuteOverride : checkable->GetCheckCommand(); CheckCommand::Ptr commandObj = CheckCommand::ExecuteOverride ? CheckCommand::ExecuteOverride : checkable->GetCheckCommand();
@ -88,19 +88,19 @@ void IdoCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult
return; return;
if (idoType.IsEmpty()) { if (idoType.IsEmpty()) {
ReportIdoCheck(checkable, commandObj, cr, "Attribute 'ido_type' must be set."); ReportIdoCheck(checkable, commandObj, cr, producer, "Attribute 'ido_type' must be set.");
return; return;
} }
if (idoName.IsEmpty()) { if (idoName.IsEmpty()) {
ReportIdoCheck(checkable, commandObj, cr, "Attribute 'ido_name' must be set."); ReportIdoCheck(checkable, commandObj, cr, producer, "Attribute 'ido_name' must be set.");
return; return;
} }
Type::Ptr type = Type::GetByName(idoType); Type::Ptr type = Type::GetByName(idoType);
if (!type || !DbConnection::TypeInstance->IsAssignableFrom(type)) { if (!type || !DbConnection::TypeInstance->IsAssignableFrom(type)) {
ReportIdoCheck(checkable, commandObj, cr, "DB IDO type '" + idoType + "' is invalid."); ReportIdoCheck(checkable, commandObj, cr, producer, "DB IDO type '" + idoType + "' is invalid.");
return; return;
} }
@ -110,14 +110,14 @@ void IdoCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult
DbConnection::Ptr conn = static_pointer_cast<DbConnection>(dtype->GetObject(idoName)); DbConnection::Ptr conn = static_pointer_cast<DbConnection>(dtype->GetObject(idoName));
if (!conn) { if (!conn) {
ReportIdoCheck(checkable, commandObj, cr, "DB IDO connection '" + idoName + "' does not exist."); ReportIdoCheck(checkable, commandObj, cr, producer, "DB IDO connection '" + idoName + "' does not exist.");
return; return;
} }
double qps = conn->GetQueryCount(60) / 60.0; double qps = conn->GetQueryCount(60) / 60.0;
if (conn->IsPaused()) { if (conn->IsPaused()) {
ReportIdoCheck(checkable, commandObj, cr, "DB IDO connection is temporarily disabled on this cluster instance.", ServiceOK); ReportIdoCheck(checkable, commandObj, cr, producer, "DB IDO connection is temporarily disabled on this cluster instance.", ServiceOK);
return; return;
} }
@ -125,10 +125,10 @@ void IdoCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult
if (!conn->GetConnected()) { if (!conn->GetConnected()) {
if (conn->GetShouldConnect()) { if (conn->GetShouldConnect()) {
ReportIdoCheck(checkable, commandObj, cr, "Could not connect to the database server.", ServiceCritical); ReportIdoCheck(checkable, commandObj, cr, producer, "Could not connect to the database server.", ServiceCritical);
} else { } else {
ReportIdoCheck( ReportIdoCheck(
checkable, commandObj, cr, checkable, commandObj, cr, producer,
"Not currently enabled: Another cluster instance is responsible for the IDO database.", ServiceOK "Not currently enabled: Another cluster instance is responsible for the IDO database.", ServiceOK
); );
} }
@ -193,5 +193,5 @@ void IdoCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult
{ new PerfdataValue("pending_queries", pendingQueries, false, "", pendingQueriesWarning, pendingQueriesCritical) } { new PerfdataValue("pending_queries", pendingQueries, false, "", pendingQueriesWarning, pendingQueriesCritical) }
})); }));
ReportIdoCheck(checkable, commandObj, cr, msgbuf.str(), state); ReportIdoCheck(checkable, commandObj, cr, producer, msgbuf.str(), state);
} }

View File

@ -18,7 +18,7 @@ class IdoCheckTask
{ {
public: public:
static void ScriptFunc(const Checkable::Ptr& service, const CheckResult::Ptr& cr, static void ScriptFunc(const Checkable::Ptr& service, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros); const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
private: private:
IdoCheckTask(); IdoCheckTask();

View File

@ -126,7 +126,8 @@ Dictionary::Ptr ApiActions::ProcessCheckResult(const ConfigObject::Ptr& object,
if (params->Contains("ttl")) if (params->Contains("ttl"))
cr->SetTtl(HttpUtility::GetLastParameter(params, "ttl")); cr->SetTtl(HttpUtility::GetLastParameter(params, "ttl"));
Result result = checkable->ProcessCheckResult(cr); Result result = checkable->ProcessCheckResult(cr, ApiListener::GetInstance()->GetWaitGroup());
switch (result) { switch (result) {
case Result::Ok: case Result::Ok:
return ApiActions::CreateResult(200, "Successfully processed check result for object '" + checkable->GetName() + "'."); return ApiActions::CreateResult(200, "Successfully processed check result for object '" + checkable->GetName() + "'.");
@ -787,7 +788,7 @@ Dictionary::Ptr ApiActions::ExecuteCommand(const ConfigObject::Ptr& object, cons
Defer resetCheckCommandOverride([]() { Defer resetCheckCommandOverride([]() {
CheckCommand::ExecuteOverride = nullptr; CheckCommand::ExecuteOverride = nullptr;
}); });
cmd->Execute(checkable, cr, execMacros, false); cmd->Execute(checkable, cr, listener->GetWaitGroup(), execMacros, false);
} }
} else if (command_type == "EventCommand") { } else if (command_type == "EventCommand") {
EventCommand::Ptr cmd = GetSingleObjectByNameUsingPermissions(EventCommand::GetTypeName(), resolved_command, ActionsHandler::AuthenticatedApiUser); EventCommand::Ptr cmd = GetSingleObjectByNameUsingPermissions(EventCommand::GetTypeName(), resolved_command, ActionsHandler::AuthenticatedApiUser);

View File

@ -14,6 +14,7 @@
#include "base/convert.hpp" #include "base/convert.hpp"
#include "base/utility.hpp" #include "base/utility.hpp"
#include "base/context.hpp" #include "base/context.hpp"
#include <shared_mutex>
using namespace icinga; using namespace icinga;
@ -96,11 +97,12 @@ double Checkable::GetLastCheck() const
return schedule_end; return schedule_end;
} }
Checkable::ProcessingResult Checkable::ProcessCheckResult(const CheckResult::Ptr& cr, const MessageOrigin::Ptr& origin) Checkable::ProcessingResult Checkable::ProcessCheckResult(const CheckResult::Ptr& cr, const WaitGroup::Ptr& producer, const MessageOrigin::Ptr& origin)
{ {
using Result = Checkable::ProcessingResult; using Result = Checkable::ProcessingResult;
VERIFY(cr); VERIFY(cr);
VERIFY(producer);
{ {
ObjectLock olock(this); ObjectLock olock(this);
@ -135,6 +137,14 @@ Checkable::ProcessingResult Checkable::ProcessCheckResult(const CheckResult::Ptr
cr->SetCheckSource(command_endpoint->GetName()); cr->SetCheckSource(command_endpoint->GetName());
} }
std::shared_lock producerLock (*producer, std::try_to_lock);
if (!producerLock) {
// Discard the check result to not delay the current reload.
// We'll re-run the check immediately after the reload.
return Result::CheckableInactive;
}
/* agent checks go through the api */ /* agent checks go through the api */
if (command_endpoint && GetExtension("agent_check")) { if (command_endpoint && GetExtension("agent_check")) {
ApiListener::Ptr listener = ApiListener::GetInstance(); ApiListener::Ptr listener = ApiListener::GetInstance();
@ -544,7 +554,7 @@ Checkable::ProcessingResult Checkable::ProcessCheckResult(const CheckResult::Ptr
return Result::Ok; return Result::Ok;
} }
void Checkable::ExecuteRemoteCheck(const Dictionary::Ptr& resolvedMacros) void Checkable::ExecuteRemoteCheck(const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros)
{ {
CONTEXT("Executing remote check for object '" << GetName() << "'"); CONTEXT("Executing remote check for object '" << GetName() << "'");
@ -555,10 +565,10 @@ void Checkable::ExecuteRemoteCheck(const Dictionary::Ptr& resolvedMacros)
cr->SetScheduleStart(scheduled_start); cr->SetScheduleStart(scheduled_start);
cr->SetExecutionStart(before_check); cr->SetExecutionStart(before_check);
GetCheckCommand()->Execute(this, cr, resolvedMacros, true); GetCheckCommand()->Execute(this, cr, producer, resolvedMacros, true);
} }
void Checkable::ExecuteCheck() void Checkable::ExecuteCheck(const WaitGroup::Ptr& producer)
{ {
CONTEXT("Executing check for object '" << GetName() << "'"); CONTEXT("Executing check for object '" << GetName() << "'");
@ -599,10 +609,10 @@ void Checkable::ExecuteCheck()
bool local = !endpoint || endpoint == Endpoint::GetLocalEndpoint(); bool local = !endpoint || endpoint == Endpoint::GetLocalEndpoint();
if (local) { if (local) {
GetCheckCommand()->Execute(this, cr, nullptr, false); GetCheckCommand()->Execute(this, cr, producer, nullptr, false);
} else { } else {
Dictionary::Ptr macros = new Dictionary(); Dictionary::Ptr macros = new Dictionary();
GetCheckCommand()->Execute(this, cr, macros, false); GetCheckCommand()->Execute(this, cr, producer, macros, false);
if (endpoint->GetConnected()) { if (endpoint->GetConnected()) {
/* perform check on remote endpoint */ /* perform check on remote endpoint */
@ -667,7 +677,7 @@ void Checkable::ExecuteCheck()
cr->SetOutput(output); cr->SetOutput(output);
ProcessCheckResult(cr); ProcessCheckResult(cr, producer);
} }
{ {

View File

@ -6,6 +6,7 @@
#include "base/function.hpp" #include "base/function.hpp"
#include "base/functionwrapper.hpp" #include "base/functionwrapper.hpp"
#include "base/scriptframe.hpp" #include "base/scriptframe.hpp"
#include "remote/apilistener.hpp"
using namespace icinga; using namespace icinga;
@ -16,7 +17,9 @@ static void CheckableProcessCheckResult(const CheckResult::Ptr& cr)
REQUIRE_NOT_NULL(self); REQUIRE_NOT_NULL(self);
if (cr) { if (cr) {
self->ProcessCheckResult(cr); auto api (ApiListener::GetInstance());
self->ProcessCheckResult(cr, api ? api->GetWaitGroup() : new StoppableWaitGroup());
} }
} }

View File

@ -12,6 +12,7 @@
#include "icinga/notification.hpp" #include "icinga/notification.hpp"
#include "icinga/comment.hpp" #include "icinga/comment.hpp"
#include "icinga/downtime.hpp" #include "icinga/downtime.hpp"
#include "base/wait-group.hpp"
#include "remote/endpoint.hpp" #include "remote/endpoint.hpp"
#include "remote/messageorigin.hpp" #include "remote/messageorigin.hpp"
#include <condition_variable> #include <condition_variable>
@ -114,15 +115,17 @@ public:
static void UpdateStatistics(const CheckResult::Ptr& cr, CheckableType type); static void UpdateStatistics(const CheckResult::Ptr& cr, CheckableType type);
void ExecuteRemoteCheck(const Dictionary::Ptr& resolvedMacros = nullptr); void ExecuteRemoteCheck(const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros = nullptr);
void ExecuteCheck(); void ExecuteCheck(const WaitGroup::Ptr& producer);
enum class ProcessingResult enum class ProcessingResult
{ {
Ok, Ok,
CheckableInactive, CheckableInactive,
NewerCheckResultPresent, NewerCheckResultPresent,
}; };
ProcessingResult ProcessCheckResult(const CheckResult::Ptr& cr, const MessageOrigin::Ptr& origin = nullptr);
ProcessingResult ProcessCheckResult(const CheckResult::Ptr& cr, const WaitGroup::Ptr& producer, const MessageOrigin::Ptr& origin = nullptr);
Endpoint::Ptr GetCommandEndpoint() const; Endpoint::Ptr GetCommandEndpoint() const;

View File

@ -11,11 +11,12 @@ REGISTER_TYPE(CheckCommand);
thread_local CheckCommand::Ptr CheckCommand::ExecuteOverride; thread_local CheckCommand::Ptr CheckCommand::ExecuteOverride;
void CheckCommand::Execute(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, void CheckCommand::Execute(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros) const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
{ {
GetExecute()->Invoke({ GetExecute()->Invoke({
checkable, checkable,
cr, cr,
producer,
resolvedMacros, resolvedMacros,
useResolvedMacros useResolvedMacros
}); });

View File

@ -23,6 +23,7 @@ public:
static thread_local CheckCommand::Ptr ExecuteOverride; static thread_local CheckCommand::Ptr ExecuteOverride;
void Execute(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, void Execute(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
const WaitGroup::Ptr& producer,
const Dictionary::Ptr& resolvedMacros = nullptr, const Dictionary::Ptr& resolvedMacros = nullptr,
bool useResolvedMacros = false); bool useResolvedMacros = false);
}; };

View File

@ -279,7 +279,7 @@ void ClusterEvents::ExecuteCheckFromQueue(const MessageOrigin::Ptr& origin, cons
if (command_type == "check_command") { if (command_type == "check_command") {
try { try {
host->ExecuteRemoteCheck(macros); host->ExecuteRemoteCheck(ApiListener::GetInstance()->GetWaitGroup(), macros);
} catch (const std::exception& ex) { } catch (const std::exception& ex) {
String output = "Exception occurred while checking '" + host->GetName() + "': " + DiagnosticInformation(ex); String output = "Exception occurred while checking '" + host->GetName() + "': " + DiagnosticInformation(ex);
ServiceState state = ServiceUnknown; ServiceState state = ServiceUnknown;

View File

@ -176,9 +176,9 @@ Value ClusterEvents::CheckResultAPIHandler(const MessageOrigin::Ptr& origin, con
} }
if (!checkable->IsPaused() && Zone::GetLocalZone() == checkable->GetZone() && endpoint == checkable->GetCommandEndpoint()) if (!checkable->IsPaused() && Zone::GetLocalZone() == checkable->GetZone() && endpoint == checkable->GetCommandEndpoint())
checkable->ProcessCheckResult(cr); checkable->ProcessCheckResult(cr, ApiListener::GetInstance()->GetWaitGroup());
else else
checkable->ProcessCheckResult(cr, origin); checkable->ProcessCheckResult(cr, ApiListener::GetInstance()->GetWaitGroup(), origin);
return Empty; return Empty;
} }

View File

@ -27,7 +27,7 @@ using namespace icinga;
boost::signals2::signal<void(double, const String&, const std::vector<String>&)> ExternalCommandProcessor::OnNewExternalCommand; boost::signals2::signal<void(double, const String&, const std::vector<String>&)> ExternalCommandProcessor::OnNewExternalCommand;
void ExternalCommandProcessor::Execute(const String& line) void ExternalCommandProcessor::Execute(const WaitGroup::Ptr& producer, const String& line)
{ {
if (line.IsEmpty()) if (line.IsEmpty())
return; return;
@ -54,10 +54,10 @@ void ExternalCommandProcessor::Execute(const String& line)
BOOST_THROW_EXCEPTION(std::invalid_argument("Missing arguments in command: " + line)); BOOST_THROW_EXCEPTION(std::invalid_argument("Missing arguments in command: " + line));
std::vector<String> argvExtra(argv.begin() + 1, argv.end()); std::vector<String> argvExtra(argv.begin() + 1, argv.end());
Execute(ts, argv[0], argvExtra); Execute(producer, ts, argv[0], argvExtra);
} }
void ExternalCommandProcessor::Execute(double time, const String& command, const std::vector<String>& arguments) void ExternalCommandProcessor::Execute(const WaitGroup::Ptr& producer, double time, const String& command, const std::vector<String>& arguments)
{ {
ExternalCommandInfo eci; ExternalCommandInfo eci;
@ -102,7 +102,7 @@ void ExternalCommandProcessor::Execute(double time, const String& command, const
OnNewExternalCommand(time, command, realArguments); OnNewExternalCommand(time, command, realArguments);
eci.Callback(time, realArguments); eci.Callback(producer, time, realArguments);
} }
void ExternalCommandProcessor::RegisterCommand(const String& command, const ExternalCommandCallback& callback, size_t minArgs, size_t maxArgs) void ExternalCommandProcessor::RegisterCommand(const String& command, const ExternalCommandCallback& callback, size_t minArgs, size_t maxArgs)
@ -115,6 +115,16 @@ void ExternalCommandProcessor::RegisterCommand(const String& command, const Exte
GetCommands()[command] = eci; GetCommands()[command] = eci;
} }
void ExternalCommandProcessor::RegisterCommand(const String& command, const ExternalCommandCallbackLite& callback, size_t minArgs, size_t maxArgs)
{
RegisterCommand(
command,
[callback](const WaitGroup::Ptr&, double time, const std::vector<String>& args) { callback(time, args); },
minArgs,
maxArgs
);
}
void ExternalCommandProcessor::RegisterCommands() void ExternalCommandProcessor::RegisterCommands()
{ {
RegisterCommand("PROCESS_HOST_CHECK_RESULT", &ExternalCommandProcessor::ProcessHostCheckResult, 3); RegisterCommand("PROCESS_HOST_CHECK_RESULT", &ExternalCommandProcessor::ProcessHostCheckResult, 3);
@ -237,7 +247,7 @@ void ExternalCommandProcessor::RegisterCommands()
RegisterCommand("DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS", &ExternalCommandProcessor::DisableServicegroupSvcNotifications, 1); RegisterCommand("DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS", &ExternalCommandProcessor::DisableServicegroupSvcNotifications, 1);
} }
void ExternalCommandProcessor::ExecuteFromFile(const String& line, std::deque< std::vector<String> >& file_queue) void ExternalCommandProcessor::ExecuteFromFile(const WaitGroup::Ptr& producer, const String& line, std::deque<std::vector<String>>& file_queue)
{ {
if (line.IsEmpty()) if (line.IsEmpty())
return; return;
@ -270,11 +280,11 @@ void ExternalCommandProcessor::ExecuteFromFile(const String& line, std::deque< s
<< "Enqueing external command file " << argvExtra[0]; << "Enqueing external command file " << argvExtra[0];
file_queue.push_back(argvExtra); file_queue.push_back(argvExtra);
} else { } else {
Execute(ts, argv[0], argvExtra); Execute(producer, ts, argv[0], argvExtra);
} }
} }
void ExternalCommandProcessor::ProcessHostCheckResult(double time, const std::vector<String>& arguments) void ExternalCommandProcessor::ProcessHostCheckResult(const WaitGroup::Ptr& producer, double time, const std::vector<String>& arguments)
{ {
Host::Ptr host = Host::GetByName(arguments[0]); Host::Ptr host = Host::GetByName(arguments[0]);
@ -318,10 +328,10 @@ void ExternalCommandProcessor::ProcessHostCheckResult(double time, const std::ve
Log(LogNotice, "ExternalCommandProcessor") Log(LogNotice, "ExternalCommandProcessor")
<< "Processing passive check result for host '" << arguments[0] << "'"; << "Processing passive check result for host '" << arguments[0] << "'";
host->ProcessCheckResult(result); host->ProcessCheckResult(result, producer);
} }
void ExternalCommandProcessor::ProcessServiceCheckResult(double time, const std::vector<String>& arguments) void ExternalCommandProcessor::ProcessServiceCheckResult(const WaitGroup::Ptr& producer, double time, const std::vector<String>& arguments)
{ {
Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]); Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
@ -356,7 +366,7 @@ void ExternalCommandProcessor::ProcessServiceCheckResult(double time, const std:
Log(LogNotice, "ExternalCommandProcessor") Log(LogNotice, "ExternalCommandProcessor")
<< "Processing passive check result for service '" << arguments[1] << "'"; << "Processing passive check result for service '" << arguments[1] << "'";
service->ProcessCheckResult(result); service->ProcessCheckResult(result, producer);
} }
void ExternalCommandProcessor::ScheduleHostCheck(double, const std::vector<String>& arguments) void ExternalCommandProcessor::ScheduleHostCheck(double, const std::vector<String>& arguments)
@ -921,7 +931,7 @@ void ExternalCommandProcessor::DisableHostgroupPassiveSvcChecks(double, const st
} }
} }
void ExternalCommandProcessor::ProcessFile(double, const std::vector<String>& arguments) void ExternalCommandProcessor::ProcessFile(const WaitGroup::Ptr& producer, double, const std::vector<String>& arguments)
{ {
std::deque< std::vector<String> > file_queue; std::deque< std::vector<String> > file_queue;
file_queue.push_back(arguments); file_queue.push_back(arguments);
@ -946,7 +956,7 @@ void ExternalCommandProcessor::ProcessFile(double, const std::vector<String>& ar
Log(LogNotice, "compat") Log(LogNotice, "compat")
<< "Executing external command: " << line; << "Executing external command: " << line;
ExecuteFromFile(line, file_queue); ExecuteFromFile(producer, line, file_queue);
} catch (const std::exception& ex) { } catch (const std::exception& ex) {
Log(LogWarning, "ExternalCommandProcessor") Log(LogWarning, "ExternalCommandProcessor")
<< "External command failed: " << DiagnosticInformation(ex); << "External command failed: " << DiagnosticInformation(ex);

View File

@ -5,6 +5,7 @@
#include "icinga/i2-icinga.hpp" #include "icinga/i2-icinga.hpp"
#include "icinga/command.hpp" #include "icinga/command.hpp"
#include "base/wait-group.hpp"
#include "base/string.hpp" #include "base/string.hpp"
#include <boost/signals2.hpp> #include <boost/signals2.hpp>
#include <vector> #include <vector>
@ -12,7 +13,8 @@
namespace icinga namespace icinga
{ {
typedef std::function<void (double, const std::vector<String>& arguments)> ExternalCommandCallback; typedef std::function<void(const WaitGroup::Ptr&, double, const std::vector<String>& arguments)> ExternalCommandCallback;
typedef std::function<void(double, const std::vector<String>& arguments)> ExternalCommandCallbackLite;
struct ExternalCommandInfo struct ExternalCommandInfo
{ {
@ -23,18 +25,18 @@ struct ExternalCommandInfo
class ExternalCommandProcessor { class ExternalCommandProcessor {
public: public:
static void Execute(const String& line); static void Execute(const WaitGroup::Ptr& producer, const String& line);
static void Execute(double time, const String& command, const std::vector<String>& arguments); static void Execute(const WaitGroup::Ptr& producer, double time, const String& command, const std::vector<String>& arguments);
static boost::signals2::signal<void(double, const String&, const std::vector<String>&)> OnNewExternalCommand; static boost::signals2::signal<void(double, const String&, const std::vector<String>&)> OnNewExternalCommand;
private: private:
ExternalCommandProcessor(); ExternalCommandProcessor();
static void ExecuteFromFile(const String& line, std::deque< std::vector<String> >& file_queue); static void ExecuteFromFile(const WaitGroup::Ptr& producer, const String& line, std::deque<std::vector<String>>& file_queue);
static void ProcessHostCheckResult(double time, const std::vector<String>& arguments); static void ProcessHostCheckResult(const WaitGroup::Ptr& producer, double time, const std::vector<String>& arguments);
static void ProcessServiceCheckResult(double time, const std::vector<String>& arguments); static void ProcessServiceCheckResult(const WaitGroup::Ptr& producer, double time, const std::vector<String>& arguments);
static void ScheduleHostCheck(double time, const std::vector<String>& arguments); static void ScheduleHostCheck(double time, const std::vector<String>& arguments);
static void ScheduleForcedHostCheck(double time, const std::vector<String>& arguments); static void ScheduleForcedHostCheck(double time, const std::vector<String>& arguments);
static void ScheduleSvcCheck(double time, const std::vector<String>& arguments); static void ScheduleSvcCheck(double time, const std::vector<String>& arguments);
@ -67,7 +69,7 @@ private:
static void DisableServicegroupPassiveSvcChecks(double time, const std::vector<String>& arguments); static void DisableServicegroupPassiveSvcChecks(double time, const std::vector<String>& arguments);
static void EnableHostgroupPassiveSvcChecks(double time, const std::vector<String>& arguments); static void EnableHostgroupPassiveSvcChecks(double time, const std::vector<String>& arguments);
static void DisableHostgroupPassiveSvcChecks(double time, const std::vector<String>& arguments); static void DisableHostgroupPassiveSvcChecks(double time, const std::vector<String>& arguments);
static void ProcessFile(double time, const std::vector<String>& arguments); static void ProcessFile(const WaitGroup::Ptr& producer, double time, const std::vector<String>& arguments);
static void ScheduleSvcDowntime(double time, const std::vector<String>& arguments); static void ScheduleSvcDowntime(double time, const std::vector<String>& arguments);
static void DelSvcDowntime(double time, const std::vector<String>& arguments); static void DelSvcDowntime(double time, const std::vector<String>& arguments);
static void ScheduleHostDowntime(double time, const std::vector<String>& arguments); static void ScheduleHostDowntime(double time, const std::vector<String>& arguments);
@ -157,6 +159,7 @@ private:
static void ChangeCustomCommandVarInternal(const Command::Ptr& command, const String& name, const Value& value); static void ChangeCustomCommandVarInternal(const Command::Ptr& command, const String& name, const Value& value);
static void RegisterCommand(const String& command, const ExternalCommandCallback& callback, size_t minArgs = 0, size_t maxArgs = UINT_MAX); static void RegisterCommand(const String& command, const ExternalCommandCallback& callback, size_t minArgs = 0, size_t maxArgs = UINT_MAX);
static void RegisterCommand(const String& command, const ExternalCommandCallbackLite& callback, size_t minArgs = 0, size_t maxArgs = UINT_MAX);
static void RegisterCommands(); static void RegisterCommands();
static std::mutex& GetMutex(); static std::mutex& GetMutex();

View File

@ -13,11 +13,11 @@
using namespace icinga; using namespace icinga;
REGISTER_FUNCTION_NONCONST(Internal, IcingadbCheck, &IcingadbCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros"); REGISTER_FUNCTION_NONCONST(Internal, IcingadbCheck, &IcingadbCheckTask::ScriptFunc, "checkable:cr:producer:resolvedMacros:useResolvedMacros");
static void ReportIcingadbCheck( static void ReportIcingadbCheck(
const Checkable::Ptr& checkable, const CheckCommand::Ptr& commandObj, const Checkable::Ptr& checkable, const CheckCommand::Ptr& commandObj,
const CheckResult::Ptr& cr, String output, ServiceState state) const CheckResult::Ptr& cr, const WaitGroup::Ptr& producer, String output, ServiceState state)
{ {
if (Checkable::ExecuteCommandProcessFinishedHandler) { if (Checkable::ExecuteCommandProcessFinishedHandler) {
double now = Utility::GetTime(); double now = Utility::GetTime();
@ -32,7 +32,7 @@ static void ReportIcingadbCheck(
} else { } else {
cr->SetState(state); cr->SetState(state);
cr->SetOutput(output); cr->SetOutput(output);
checkable->ProcessCheckResult(cr); checkable->ProcessCheckResult(cr, producer);
} }
} }
@ -43,7 +43,7 @@ double GetXMessageTs(const Array::Ptr& xMessage)
} }
void IcingadbCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, void IcingadbCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros) const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
{ {
CheckCommand::Ptr commandObj = CheckCommand::ExecuteOverride ? CheckCommand::ExecuteOverride : checkable->GetCheckCommand(); CheckCommand::Ptr commandObj = CheckCommand::ExecuteOverride ? CheckCommand::ExecuteOverride : checkable->GetCheckCommand();
@ -87,21 +87,21 @@ void IcingadbCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckR
return; return;
if (icingadbName.IsEmpty()) { if (icingadbName.IsEmpty()) {
ReportIcingadbCheck(checkable, commandObj, cr, "Icinga DB UNKNOWN: Attribute 'icingadb_name' must be set.", ServiceUnknown); ReportIcingadbCheck(checkable, commandObj, cr, producer, "Icinga DB UNKNOWN: Attribute 'icingadb_name' must be set.", ServiceUnknown);
return; return;
} }
auto conn (IcingaDB::GetByName(icingadbName)); auto conn (IcingaDB::GetByName(icingadbName));
if (!conn) { if (!conn) {
ReportIcingadbCheck(checkable, commandObj, cr, "Icinga DB UNKNOWN: Icinga DB connection '" + icingadbName + "' does not exist.", ServiceUnknown); ReportIcingadbCheck(checkable, commandObj, cr, producer, "Icinga DB UNKNOWN: Icinga DB connection '" + icingadbName + "' does not exist.", ServiceUnknown);
return; return;
} }
auto redis (conn->GetConnection()); auto redis (conn->GetConnection());
if (!redis || !redis->GetConnected()) { if (!redis || !redis->GetConnected()) {
ReportIcingadbCheck(checkable, commandObj, cr, "Icinga DB CRITICAL: Not connected to Redis.", ServiceCritical); ReportIcingadbCheck(checkable, commandObj, cr, producer, "Icinga DB CRITICAL: Not connected to Redis.", ServiceCritical);
return; return;
} }
@ -136,7 +136,7 @@ void IcingadbCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckR
xReadHistoryBacklog = std::move(replies.at(4)); xReadHistoryBacklog = std::move(replies.at(4));
} catch (const std::exception& ex) { } catch (const std::exception& ex) {
ReportIcingadbCheck( ReportIcingadbCheck(
checkable, commandObj, cr, checkable, commandObj, cr, producer,
String("Icinga DB CRITICAL: Could not query Redis: ") + ex.what(), ServiceCritical String("Icinga DB CRITICAL: Could not query Redis: ") + ex.what(), ServiceCritical
); );
return; return;
@ -144,7 +144,7 @@ void IcingadbCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckR
if (!xReadHeartbeat) { if (!xReadHeartbeat) {
ReportIcingadbCheck( ReportIcingadbCheck(
checkable, commandObj, cr, checkable, commandObj, cr, producer,
"Icinga DB CRITICAL: The Icinga DB daemon seems to have never run. (Missing heartbeat)", "Icinga DB CRITICAL: The Icinga DB daemon seems to have never run. (Missing heartbeat)",
ServiceCritical ServiceCritical
); );
@ -511,5 +511,5 @@ void IcingadbCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckR
} }
cr->SetPerformanceData(perfdata); cr->SetPerformanceData(perfdata);
ReportIcingadbCheck(checkable, commandObj, cr, msgbuf.str(), state); ReportIcingadbCheck(checkable, commandObj, cr, producer, msgbuf.str(), state);
} }

View File

@ -18,7 +18,7 @@ class IcingadbCheckTask
{ {
public: public:
static void ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, static void ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros); const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
private: private:
IcingadbCheckTask(); IcingadbCheckTask();

View File

@ -112,6 +112,7 @@ void LivestatusListener::Stop(bool runtimeRemoved)
<< "'" << GetName() << "' stopped."; << "'" << GetName() << "' stopped.";
m_Listener->Close(); m_Listener->Close();
m_WaitGroup->Join();
if (m_Thread.joinable()) if (m_Thread.joinable())
m_Thread.join(); m_Thread.join();
@ -191,7 +192,7 @@ void LivestatusListener::ClientHandler(const Socket::Ptr& client)
break; break;
LivestatusQuery::Ptr query = new LivestatusQuery(lines, GetCompatLogPath()); LivestatusQuery::Ptr query = new LivestatusQuery(lines, GetCompatLogPath());
if (!query->Execute(stream)) if (!query->Execute(m_WaitGroup, stream))
break; break;
} }

View File

@ -7,6 +7,7 @@
#include "livestatus/livestatuslistener-ti.hpp" #include "livestatus/livestatuslistener-ti.hpp"
#include "livestatus/livestatusquery.hpp" #include "livestatus/livestatusquery.hpp"
#include "base/socket.hpp" #include "base/socket.hpp"
#include "base/wait-group.hpp"
#include <thread> #include <thread>
using namespace icinga; using namespace icinga;
@ -40,6 +41,7 @@ private:
Socket::Ptr m_Listener; Socket::Ptr m_Listener;
std::thread m_Thread; std::thread m_Thread;
StoppableWaitGroup::Ptr m_WaitGroup = new StoppableWaitGroup();
}; };
} }

View File

@ -570,7 +570,7 @@ void LivestatusQuery::ExecuteGetHelper(const Stream::Ptr& stream)
SendResponse(stream, LivestatusErrorOK, result.str()); SendResponse(stream, LivestatusErrorOK, result.str());
} }
void LivestatusQuery::ExecuteCommandHelper(const Stream::Ptr& stream) void LivestatusQuery::ExecuteCommandHelper(const WaitGroup::Ptr& producer, const Stream::Ptr& stream)
{ {
{ {
std::unique_lock<std::mutex> lock(l_QueryMutex); std::unique_lock<std::mutex> lock(l_QueryMutex);
@ -580,7 +580,7 @@ void LivestatusQuery::ExecuteCommandHelper(const Stream::Ptr& stream)
Log(LogNotice, "LivestatusQuery") Log(LogNotice, "LivestatusQuery")
<< "Executing command: " << m_Command; << "Executing command: " << m_Command;
ExternalCommandProcessor::Execute(m_Command); ExternalCommandProcessor::Execute(producer, m_Command);
SendResponse(stream, LivestatusErrorOK, ""); SendResponse(stream, LivestatusErrorOK, "");
} }
@ -621,7 +621,7 @@ void LivestatusQuery::PrintFixed16(const Stream::Ptr& stream, int code, const St
} }
} }
bool LivestatusQuery::Execute(const Stream::Ptr& stream) bool LivestatusQuery::Execute(const WaitGroup::Ptr& producer, const Stream::Ptr& stream)
{ {
try { try {
Log(LogNotice, "LivestatusQuery") Log(LogNotice, "LivestatusQuery")
@ -630,7 +630,7 @@ bool LivestatusQuery::Execute(const Stream::Ptr& stream)
if (m_Verb == "GET") if (m_Verb == "GET")
ExecuteGetHelper(stream); ExecuteGetHelper(stream);
else if (m_Verb == "COMMAND") else if (m_Verb == "COMMAND")
ExecuteCommandHelper(stream); ExecuteCommandHelper(producer, stream);
else if (m_Verb == "ERROR") else if (m_Verb == "ERROR")
ExecuteErrorHelper(stream); ExecuteErrorHelper(stream);
else else

View File

@ -5,6 +5,7 @@
#include "livestatus/filter.hpp" #include "livestatus/filter.hpp"
#include "livestatus/aggregator.hpp" #include "livestatus/aggregator.hpp"
#include "base/wait-group.hpp"
#include "base/object.hpp" #include "base/object.hpp"
#include "base/array.hpp" #include "base/array.hpp"
#include "base/stream.hpp" #include "base/stream.hpp"
@ -33,7 +34,7 @@ public:
LivestatusQuery(const std::vector<String>& lines, const String& compat_log_path); LivestatusQuery(const std::vector<String>& lines, const String& compat_log_path);
bool Execute(const Stream::Ptr& stream); bool Execute(const WaitGroup::Ptr& producer, const Stream::Ptr& stream);
static int GetExternalCommands(); static int GetExternalCommands();
@ -76,7 +77,7 @@ private:
static String QuoteStringPython(const String& str); static String QuoteStringPython(const String& str);
void ExecuteGetHelper(const Stream::Ptr& stream); void ExecuteGetHelper(const Stream::Ptr& stream);
void ExecuteCommandHelper(const Stream::Ptr& stream); void ExecuteCommandHelper(const WaitGroup::Ptr& producer, const Stream::Ptr& stream);
void ExecuteErrorHelper(const Stream::Ptr& stream); void ExecuteErrorHelper(const Stream::Ptr& stream);
void SendResponse(const Stream::Ptr& stream, int code, const String& data); void SendResponse(const Stream::Ptr& stream, int code, const String& data);

View File

@ -17,10 +17,10 @@
using namespace icinga; using namespace icinga;
REGISTER_FUNCTION_NONCONST(Internal, ClusterCheck, &ClusterCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros"); REGISTER_FUNCTION_NONCONST(Internal, ClusterCheck, &ClusterCheckTask::ScriptFunc, "checkable:cr:producer:resolvedMacros:useResolvedMacros");
void ClusterCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, void ClusterCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros) const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
{ {
REQUIRE_NOT_NULL(checkable); REQUIRE_NOT_NULL(checkable);
REQUIRE_NOT_NULL(cr); REQUIRE_NOT_NULL(cr);
@ -47,7 +47,7 @@ void ClusterCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckRe
} else { } else {
cr->SetOutput(output); cr->SetOutput(output);
cr->SetState(ServiceUnknown); cr->SetState(ServiceUnknown);
checkable->ProcessCheckResult(cr); checkable->ProcessCheckResult(cr, producer);
} }
return; return;
@ -92,7 +92,7 @@ void ClusterCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckRe
cr->SetState(state); cr->SetState(state);
cr->SetOutput(output); cr->SetOutput(output);
checkable->ProcessCheckResult(cr); checkable->ProcessCheckResult(cr, producer);
} }
} }

View File

@ -17,7 +17,7 @@ class ClusterCheckTask
{ {
public: public:
static void ScriptFunc(const Checkable::Ptr& service, const CheckResult::Ptr& cr, static void ScriptFunc(const Checkable::Ptr& service, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros); const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
private: private:
ClusterCheckTask(); ClusterCheckTask();

View File

@ -12,10 +12,10 @@
using namespace icinga; using namespace icinga;
REGISTER_FUNCTION_NONCONST(Internal, ClusterZoneCheck, &ClusterZoneCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros"); REGISTER_FUNCTION_NONCONST(Internal, ClusterZoneCheck, &ClusterZoneCheckTask::ScriptFunc, "checkable:cr:producer:resolvedMacros:useResolvedMacros");
void ClusterZoneCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, void ClusterZoneCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros) const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
{ {
REQUIRE_NOT_NULL(checkable); REQUIRE_NOT_NULL(checkable);
REQUIRE_NOT_NULL(cr); REQUIRE_NOT_NULL(cr);
@ -42,7 +42,7 @@ void ClusterZoneCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const Che
cr->SetCommand(commandName); cr->SetCommand(commandName);
cr->SetOutput(output); cr->SetOutput(output);
cr->SetState(state); cr->SetState(state);
checkable->ProcessCheckResult(cr); checkable->ProcessCheckResult(cr, producer);
} }
return; return;
@ -97,7 +97,7 @@ void ClusterZoneCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const Che
cr->SetCommand(commandName); cr->SetCommand(commandName);
cr->SetOutput(output); cr->SetOutput(output);
cr->SetState(state); cr->SetState(state);
checkable->ProcessCheckResult(cr); checkable->ProcessCheckResult(cr, producer);
} }
return; return;
@ -123,7 +123,7 @@ void ClusterZoneCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const Che
cr->SetCommand(commandName); cr->SetCommand(commandName);
cr->SetOutput(output); cr->SetOutput(output);
cr->SetState(state); cr->SetState(state);
checkable->ProcessCheckResult(cr); checkable->ProcessCheckResult(cr, producer);
} }
return; return;
} }
@ -213,6 +213,6 @@ void ClusterZoneCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const Che
new PerfdataValue("sum_bytes_received_per_second", bytesReceivedPerSecond) new PerfdataValue("sum_bytes_received_per_second", bytesReceivedPerSecond)
})); }));
checkable->ProcessCheckResult(cr); checkable->ProcessCheckResult(cr, producer);
} }
} }

View File

@ -17,7 +17,7 @@ class ClusterZoneCheckTask
{ {
public: public:
static void ScriptFunc(const Checkable::Ptr& service, const CheckResult::Ptr& cr, static void ScriptFunc(const Checkable::Ptr& service, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros); const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
private: private:
ClusterZoneCheckTask(); ClusterZoneCheckTask();

View File

@ -13,10 +13,10 @@
using namespace icinga; using namespace icinga;
REGISTER_FUNCTION_NONCONST(Internal, DummyCheck, &DummyCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros"); REGISTER_FUNCTION_NONCONST(Internal, DummyCheck, &DummyCheckTask::ScriptFunc, "checkable:cr:producer:resolvedMacros:useResolvedMacros");
void DummyCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, void DummyCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros) const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
{ {
REQUIRE_NOT_NULL(checkable); REQUIRE_NOT_NULL(checkable);
REQUIRE_NOT_NULL(cr); REQUIRE_NOT_NULL(cr);
@ -70,6 +70,6 @@ void DummyCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResu
cr->SetExecutionEnd(now); cr->SetExecutionEnd(now);
cr->SetCommand(commandName); cr->SetCommand(commandName);
checkable->ProcessCheckResult(cr); checkable->ProcessCheckResult(cr, producer);
} }
} }

View File

@ -19,7 +19,7 @@ class DummyCheckTask
{ {
public: public:
static void ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, static void ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros); const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
private: private:
DummyCheckTask(); DummyCheckTask();

View File

@ -12,10 +12,10 @@
using namespace icinga; using namespace icinga;
REGISTER_FUNCTION_NONCONST(Internal, ExceptionCheck, &ExceptionCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros"); REGISTER_FUNCTION_NONCONST(Internal, ExceptionCheck, &ExceptionCheckTask::ScriptFunc, "checkable:cr:producer:resolvedMacros:useResolvedMacros");
void ExceptionCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, void ExceptionCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros) const WaitGroup::Ptr&, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
{ {
REQUIRE_NOT_NULL(checkable); REQUIRE_NOT_NULL(checkable);
REQUIRE_NOT_NULL(cr); REQUIRE_NOT_NULL(cr);

View File

@ -18,7 +18,7 @@ class ExceptionCheckTask
{ {
public: public:
static void ScriptFunc(const Checkable::Ptr& service, const CheckResult::Ptr& cr, static void ScriptFunc(const Checkable::Ptr& service, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros); const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
private: private:
ExceptionCheckTask(); ExceptionCheckTask();

View File

@ -17,10 +17,10 @@
using namespace icinga; using namespace icinga;
REGISTER_FUNCTION_NONCONST(Internal, IcingaCheck, &IcingaCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros"); REGISTER_FUNCTION_NONCONST(Internal, IcingaCheck, &IcingaCheckTask::ScriptFunc, "checkable:cr:producer:resolvedMacros:useResolvedMacros");
void IcingaCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, void IcingaCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros) const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
{ {
REQUIRE_NOT_NULL(checkable); REQUIRE_NOT_NULL(checkable);
REQUIRE_NOT_NULL(cr); REQUIRE_NOT_NULL(cr);
@ -204,6 +204,6 @@ void IcingaCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckRes
cr->SetOutput(output); cr->SetOutput(output);
cr->SetCommand(commandName); cr->SetCommand(commandName);
checkable->ProcessCheckResult(cr); checkable->ProcessCheckResult(cr, producer);
} }
} }

View File

@ -18,7 +18,7 @@ class IcingaCheckTask
{ {
public: public:
static void ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, static void ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros); const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
private: private:
IcingaCheckTask(); IcingaCheckTask();

View File

@ -31,7 +31,7 @@
using namespace icinga; using namespace icinga;
REGISTER_FUNCTION_NONCONST(Internal, IfwApiCheck, &IfwApiCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros"); REGISTER_FUNCTION_NONCONST(Internal, IfwApiCheck, &IfwApiCheckTask::ScriptFunc, "checkable:cr:producer:resolvedMacros:useResolvedMacros");
static const char* GetUnderstandableError(const std::exception& ex) static const char* GetUnderstandableError(const std::exception& ex)
{ {
@ -194,7 +194,7 @@ static void DoIfwNetIo(
} }
void IfwApiCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, void IfwApiCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros) const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
{ {
namespace asio = boost::asio; namespace asio = boost::asio;
namespace http = boost::beast::http; namespace http = boost::beast::http;
@ -213,7 +213,7 @@ void IfwApiCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckRes
if (!(commandEndpoint->GetCapabilities() & (uint_fast64_t)ApiCapabilities::IfwApiCheckCommand)) { if (!(commandEndpoint->GetCapabilities() & (uint_fast64_t)ApiCapabilities::IfwApiCheckCommand)) {
// Assume "ifw-api-check-command" has been imported into a check command which can also work // Assume "ifw-api-check-command" has been imported into a check command which can also work
// based on "plugin-check-command", delegate respectively and hope for the best // based on "plugin-check-command", delegate respectively and hope for the best
PluginCheckTask::ScriptFunc(checkable, cr, resolvedMacros, useResolvedMacros); PluginCheckTask::ScriptFunc(checkable, cr, producer, resolvedMacros, useResolvedMacros);
return; return;
} }
} }
@ -275,7 +275,7 @@ void IfwApiCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckRes
callback(cr->GetCommand(), pr); callback(cr->GetCommand(), pr);
}; };
} else { } else {
reportResult = [checkable, cr]() { checkable->ProcessCheckResult(cr); }; reportResult = [checkable, cr, producer] { checkable->ProcessCheckResult(cr, producer); };
} }
// Set the default check result state and exit code to unknown for the moment! // Set the default check result state and exit code to unknown for the moment!

View File

@ -18,7 +18,7 @@ class IfwApiCheckTask
{ {
public: public:
static void ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, static void ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros); const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
private: private:
IfwApiCheckTask(); IfwApiCheckTask();

View File

@ -13,10 +13,10 @@
using namespace icinga; using namespace icinga;
REGISTER_FUNCTION_NONCONST(Internal, NullCheck, &NullCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros"); REGISTER_FUNCTION_NONCONST(Internal, NullCheck, &NullCheckTask::ScriptFunc, "checkable:cr:producer:resolvedMacros:useResolvedMacros");
void NullCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, void NullCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros) const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
{ {
REQUIRE_NOT_NULL(checkable); REQUIRE_NOT_NULL(checkable);
REQUIRE_NOT_NULL(cr); REQUIRE_NOT_NULL(cr);
@ -45,6 +45,6 @@ void NullCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResul
})); }));
cr->SetState(state); cr->SetState(state);
checkable->ProcessCheckResult(cr); checkable->ProcessCheckResult(cr, producer);
} }
} }

View File

@ -19,7 +19,7 @@ class NullCheckTask
{ {
public: public:
static void ScriptFunc(const Checkable::Ptr& service, const CheckResult::Ptr& cr, static void ScriptFunc(const Checkable::Ptr& service, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros); const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
private: private:
NullCheckTask(); NullCheckTask();

View File

@ -14,10 +14,10 @@
using namespace icinga; using namespace icinga;
REGISTER_FUNCTION_NONCONST(Internal, PluginCheck, &PluginCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros"); REGISTER_FUNCTION_NONCONST(Internal, PluginCheck, &PluginCheckTask::ScriptFunc, "checkable:cr:producer:resolvedMacros:useResolvedMacros");
void PluginCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, void PluginCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros) const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
{ {
REQUIRE_NOT_NULL(checkable); REQUIRE_NOT_NULL(checkable);
REQUIRE_NOT_NULL(cr); REQUIRE_NOT_NULL(cr);
@ -48,8 +48,8 @@ void PluginCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckRes
if (Checkable::ExecuteCommandProcessFinishedHandler) { if (Checkable::ExecuteCommandProcessFinishedHandler) {
callback = Checkable::ExecuteCommandProcessFinishedHandler; callback = Checkable::ExecuteCommandProcessFinishedHandler;
} else { } else {
callback = [checkable, cr](const Value& commandLine, const ProcessResult& pr) { callback = [checkable, cr, producer](const Value& commandLine, const ProcessResult& pr) {
ProcessFinishedHandler(checkable, cr, commandLine, pr); ProcessFinishedHandler(checkable, cr, producer, commandLine, pr);
}; };
} }
@ -62,7 +62,8 @@ void PluginCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckRes
} }
} }
void PluginCheckTask::ProcessFinishedHandler(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, const Value& commandLine, const ProcessResult& pr) void PluginCheckTask::ProcessFinishedHandler(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
const WaitGroup::Ptr& producer, const Value& commandLine, const ProcessResult& pr)
{ {
Checkable::CurrentConcurrentChecks.fetch_sub(1); Checkable::CurrentConcurrentChecks.fetch_sub(1);
Checkable::DecreasePendingChecks(); Checkable::DecreasePendingChecks();
@ -93,5 +94,5 @@ void PluginCheckTask::ProcessFinishedHandler(const Checkable::Ptr& checkable, co
cr->SetExecutionStart(pr.ExecutionStart); cr->SetExecutionStart(pr.ExecutionStart);
cr->SetExecutionEnd(pr.ExecutionEnd); cr->SetExecutionEnd(pr.ExecutionEnd);
checkable->ProcessCheckResult(cr); checkable->ProcessCheckResult(cr, producer);
} }

View File

@ -19,13 +19,13 @@ class PluginCheckTask
{ {
public: public:
static void ScriptFunc(const Checkable::Ptr& service, const CheckResult::Ptr& cr, static void ScriptFunc(const Checkable::Ptr& service, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros); const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
private: private:
PluginCheckTask(); PluginCheckTask();
static void ProcessFinishedHandler(const Checkable::Ptr& service, static void ProcessFinishedHandler(const Checkable::Ptr& service, const CheckResult::Ptr& cr,
const CheckResult::Ptr& cr, const Value& commandLine, const ProcessResult& pr); const WaitGroup::Ptr& producer, const Value& commandLine, const ProcessResult& pr);
}; };
} }

View File

@ -13,10 +13,10 @@
using namespace icinga; using namespace icinga;
REGISTER_FUNCTION_NONCONST(Internal, RandomCheck, &RandomCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros"); REGISTER_FUNCTION_NONCONST(Internal, RandomCheck, &RandomCheckTask::ScriptFunc, "checkable:cr:producer:resolvedMacros:useResolvedMacros");
void RandomCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, void RandomCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros) const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
{ {
REQUIRE_NOT_NULL(checkable); REQUIRE_NOT_NULL(checkable);
REQUIRE_NOT_NULL(cr); REQUIRE_NOT_NULL(cr);
@ -60,6 +60,6 @@ void RandomCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckRes
cr->SetState(state); cr->SetState(state);
cr->SetCommand(commandName); cr->SetCommand(commandName);
checkable->ProcessCheckResult(cr); checkable->ProcessCheckResult(cr, producer);
} }
} }

View File

@ -18,7 +18,7 @@ class RandomCheckTask
{ {
public: public:
static void ScriptFunc(const Checkable::Ptr& service, const CheckResult::Ptr& cr, static void ScriptFunc(const Checkable::Ptr& service, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros); const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
private: private:
RandomCheckTask(); RandomCheckTask();

View File

@ -9,10 +9,10 @@
using namespace icinga; using namespace icinga;
REGISTER_FUNCTION_NONCONST(Internal, SleepCheck, &SleepCheckTask::ScriptFunc, "checkable:cr:resolvedMacros:useResolvedMacros"); REGISTER_FUNCTION_NONCONST(Internal, SleepCheck, &SleepCheckTask::ScriptFunc, "checkable:cr:producer:resolvedMacros:useResolvedMacros");
void SleepCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, void SleepCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros) const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
{ {
REQUIRE_NOT_NULL(checkable); REQUIRE_NOT_NULL(checkable);
REQUIRE_NOT_NULL(cr); REQUIRE_NOT_NULL(cr);
@ -62,6 +62,6 @@ void SleepCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResu
cr->SetExecutionEnd(now); cr->SetExecutionEnd(now);
cr->SetCommand(commandName); cr->SetCommand(commandName);
checkable->ProcessCheckResult(cr); checkable->ProcessCheckResult(cr, producer);
} }
} }

View File

@ -19,7 +19,7 @@ class SleepCheckTask
{ {
public: public:
static void ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, static void ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros); const WaitGroup::Ptr& producer, const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
private: private:
SleepCheckTask(); SleepCheckTask();

View File

@ -368,6 +368,7 @@ void ApiListener::Stop(bool runtimeDeleted)
m_Timer->Stop(true); m_Timer->Stop(true);
m_RenewOwnCertTimer->Stop(true); m_RenewOwnCertTimer->Stop(true);
m_WaitGroup->Join();
ObjectImpl<ApiListener>::Stop(runtimeDeleted); ObjectImpl<ApiListener>::Stop(runtimeDeleted);
Log(LogInformation, "ApiListener") Log(LogInformation, "ApiListener")

View File

@ -16,6 +16,7 @@
#include "base/tcpsocket.hpp" #include "base/tcpsocket.hpp"
#include "base/tlsstream.hpp" #include "base/tlsstream.hpp"
#include "base/threadpool.hpp" #include "base/threadpool.hpp"
#include "base/wait-group.hpp"
#include <atomic> #include <atomic>
#include <boost/asio/io_context.hpp> #include <boost/asio/io_context.hpp>
#include <boost/asio/ip/tcp.hpp> #include <boost/asio/ip/tcp.hpp>
@ -151,6 +152,11 @@ public:
double GetTlsHandshakeTimeout() const override; double GetTlsHandshakeTimeout() const override;
void SetTlsHandshakeTimeout(double value, bool suppress_events, const Value& cookie) override; void SetTlsHandshakeTimeout(double value, bool suppress_events, const Value& cookie) override;
WaitGroup::Ptr GetWaitGroup() const
{
return m_WaitGroup;
}
protected: protected:
void OnConfigLoaded() override; void OnConfigLoaded() override;
void OnAllConfigLoaded() override; void OnAllConfigLoaded() override;
@ -177,6 +183,7 @@ private:
Timer::Ptr m_RenewOwnCertTimer; Timer::Ptr m_RenewOwnCertTimer;
Endpoint::Ptr m_LocalEndpoint; Endpoint::Ptr m_LocalEndpoint;
StoppableWaitGroup::Ptr m_WaitGroup = new StoppableWaitGroup();
static ApiListener::Ptr m_Instance; static ApiListener::Ptr m_Instance;
static std::atomic<bool> m_UpdatedObjectAuthority; static std::atomic<bool> m_UpdatedObjectAuthority;

View File

@ -73,7 +73,7 @@ BOOST_AUTO_TEST_CASE(host_not_flapping)
int i = 0; int i = 0;
while (i++ < 10) { while (i++ < 10) {
// For some reason, elusive to me, the first check is a state change // For some reason, elusive to me, the first check is a state change
host->ProcessCheckResult(MakeCheckResult(ServiceOK)); host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
LogFlapping(host); LogFlapping(host);
LogHostStatus(host); LogHostStatus(host);
@ -107,9 +107,9 @@ BOOST_AUTO_TEST_CASE(host_flapping)
int i = 0; int i = 0;
while (i++ < 25) { while (i++ < 25) {
if (i % 2) if (i % 2)
host->ProcessCheckResult(MakeCheckResult(ServiceOK)); host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
else else
host->ProcessCheckResult(MakeCheckResult(ServiceWarning)); host->ProcessCheckResult(MakeCheckResult(ServiceWarning), new StoppableWaitGroup());
LogFlapping(host); LogFlapping(host);
LogHostStatus(host); LogHostStatus(host);
@ -144,18 +144,18 @@ BOOST_AUTO_TEST_CASE(host_flapping_recover)
Utility::SetTime(0); Utility::SetTime(0);
// A few warning // A few warning
host->ProcessCheckResult(MakeCheckResult(ServiceWarning)); host->ProcessCheckResult(MakeCheckResult(ServiceWarning), new StoppableWaitGroup());
host->ProcessCheckResult(MakeCheckResult(ServiceWarning)); host->ProcessCheckResult(MakeCheckResult(ServiceWarning), new StoppableWaitGroup());
host->ProcessCheckResult(MakeCheckResult(ServiceWarning)); host->ProcessCheckResult(MakeCheckResult(ServiceWarning), new StoppableWaitGroup());
host->ProcessCheckResult(MakeCheckResult(ServiceWarning)); host->ProcessCheckResult(MakeCheckResult(ServiceWarning), new StoppableWaitGroup());
LogFlapping(host); LogFlapping(host);
LogHostStatus(host); LogHostStatus(host);
for (int i = 0; i <= 7; i++) { for (int i = 0; i <= 7; i++) {
if (i % 2) if (i % 2)
host->ProcessCheckResult(MakeCheckResult(ServiceOK)); host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
else else
host->ProcessCheckResult(MakeCheckResult(ServiceWarning)); host->ProcessCheckResult(MakeCheckResult(ServiceWarning), new StoppableWaitGroup());
} }
LogFlapping(host); LogFlapping(host);
@ -171,7 +171,7 @@ BOOST_AUTO_TEST_CASE(host_flapping_recover)
BOOST_CHECK(host->GetFlappingCurrent() > 25.0); BOOST_CHECK(host->GetFlappingCurrent() > 25.0);
BOOST_CHECK(host->IsFlapping()); BOOST_CHECK(host->IsFlapping());
host->ProcessCheckResult(MakeCheckResult(ServiceWarning)); host->ProcessCheckResult(MakeCheckResult(ServiceWarning), new StoppableWaitGroup());
LogFlapping(host); LogFlapping(host);
LogHostStatus(host); LogHostStatus(host);
count++; count++;
@ -203,40 +203,40 @@ BOOST_AUTO_TEST_CASE(host_flapping_docs_example)
Utility::SetTime(0); Utility::SetTime(0);
host->ProcessCheckResult(MakeCheckResult(ServiceCritical)); host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
host->ProcessCheckResult(MakeCheckResult(ServiceCritical)); host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
host->ProcessCheckResult(MakeCheckResult(ServiceCritical)); host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
host->ProcessCheckResult(MakeCheckResult(ServiceWarning)); host->ProcessCheckResult(MakeCheckResult(ServiceWarning), new StoppableWaitGroup());
host->ProcessCheckResult(MakeCheckResult(ServiceCritical)); host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
host->ProcessCheckResult(MakeCheckResult(ServiceWarning)); host->ProcessCheckResult(MakeCheckResult(ServiceWarning), new StoppableWaitGroup());
host->ProcessCheckResult(MakeCheckResult(ServiceOK)); host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
host->ProcessCheckResult(MakeCheckResult(ServiceOK)); host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
host->ProcessCheckResult(MakeCheckResult(ServiceOK)); host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
host->ProcessCheckResult(MakeCheckResult(ServiceOK)); host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
host->ProcessCheckResult(MakeCheckResult(ServiceWarning)); host->ProcessCheckResult(MakeCheckResult(ServiceWarning), new StoppableWaitGroup());
host->ProcessCheckResult(MakeCheckResult(ServiceWarning)); host->ProcessCheckResult(MakeCheckResult(ServiceWarning), new StoppableWaitGroup());
host->ProcessCheckResult(MakeCheckResult(ServiceWarning)); host->ProcessCheckResult(MakeCheckResult(ServiceWarning), new StoppableWaitGroup());
host->ProcessCheckResult(MakeCheckResult(ServiceWarning)); host->ProcessCheckResult(MakeCheckResult(ServiceWarning), new StoppableWaitGroup());
host->ProcessCheckResult(MakeCheckResult(ServiceOK)); host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
host->ProcessCheckResult(MakeCheckResult(ServiceOK)); host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
host->ProcessCheckResult(MakeCheckResult(ServiceOK)); host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
host->ProcessCheckResult(MakeCheckResult(ServiceWarning)); host->ProcessCheckResult(MakeCheckResult(ServiceWarning), new StoppableWaitGroup());
host->ProcessCheckResult(MakeCheckResult(ServiceWarning)); host->ProcessCheckResult(MakeCheckResult(ServiceWarning), new StoppableWaitGroup());
host->ProcessCheckResult(MakeCheckResult(ServiceWarning)); host->ProcessCheckResult(MakeCheckResult(ServiceWarning), new StoppableWaitGroup());
host->ProcessCheckResult(MakeCheckResult(ServiceCritical)); host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
LogFlapping(host); LogFlapping(host);
LogHostStatus(host); LogHostStatus(host);
BOOST_CHECK(host->GetFlappingCurrent() == 39.1); BOOST_CHECK(host->GetFlappingCurrent() == 39.1);
BOOST_CHECK(host->IsFlapping()); BOOST_CHECK(host->IsFlapping());
host->ProcessCheckResult(MakeCheckResult(ServiceCritical)); host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
host->ProcessCheckResult(MakeCheckResult(ServiceCritical)); host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
host->ProcessCheckResult(MakeCheckResult(ServiceCritical)); host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
host->ProcessCheckResult(MakeCheckResult(ServiceCritical)); host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
host->ProcessCheckResult(MakeCheckResult(ServiceCritical)); host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
host->ProcessCheckResult(MakeCheckResult(ServiceCritical)); host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
host->ProcessCheckResult(MakeCheckResult(ServiceCritical)); host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
LogFlapping(host); LogFlapping(host);
LogHostStatus(host); LogHostStatus(host);

View File

@ -69,7 +69,7 @@ BOOST_AUTO_TEST_CASE(host_1attempt)
CheckNotification(host, false); CheckNotification(host, false);
std::cout << "First check result (unknown)" << std::endl; std::cout << "First check result (unknown)" << std::endl;
host->ProcessCheckResult(MakeCheckResult(ServiceUnknown)); host->ProcessCheckResult(MakeCheckResult(ServiceUnknown), new StoppableWaitGroup());
BOOST_CHECK(host->GetState() == HostDown); BOOST_CHECK(host->GetState() == HostDown);
BOOST_CHECK(host->GetStateType() == StateTypeHard); BOOST_CHECK(host->GetStateType() == StateTypeHard);
BOOST_CHECK(host->GetCheckAttempt() == 1); BOOST_CHECK(host->GetCheckAttempt() == 1);
@ -77,7 +77,7 @@ BOOST_AUTO_TEST_CASE(host_1attempt)
CheckNotification(host, true, NotificationProblem); CheckNotification(host, true, NotificationProblem);
std::cout << "Second check result (ok)" << std::endl; std::cout << "Second check result (ok)" << std::endl;
host->ProcessCheckResult(MakeCheckResult(ServiceOK)); host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
BOOST_CHECK(host->GetState() == HostUp); BOOST_CHECK(host->GetState() == HostUp);
BOOST_CHECK(host->GetStateType() == StateTypeHard); BOOST_CHECK(host->GetStateType() == StateTypeHard);
BOOST_CHECK(host->GetCheckAttempt() == 1); BOOST_CHECK(host->GetCheckAttempt() == 1);
@ -85,7 +85,7 @@ BOOST_AUTO_TEST_CASE(host_1attempt)
CheckNotification(host, true, NotificationRecovery); CheckNotification(host, true, NotificationRecovery);
std::cout << "Third check result (critical)" << std::endl; std::cout << "Third check result (critical)" << std::endl;
host->ProcessCheckResult(MakeCheckResult(ServiceCritical)); host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
BOOST_CHECK(host->GetState() == HostDown); BOOST_CHECK(host->GetState() == HostDown);
BOOST_CHECK(host->GetStateType() == StateTypeHard); BOOST_CHECK(host->GetStateType() == StateTypeHard);
BOOST_CHECK(host->GetCheckAttempt() == 1); BOOST_CHECK(host->GetCheckAttempt() == 1);
@ -93,7 +93,7 @@ BOOST_AUTO_TEST_CASE(host_1attempt)
CheckNotification(host, true, NotificationProblem); CheckNotification(host, true, NotificationProblem);
std::cout << "Fourth check result (ok)" << std::endl; std::cout << "Fourth check result (ok)" << std::endl;
host->ProcessCheckResult(MakeCheckResult(ServiceOK)); host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
BOOST_CHECK(host->GetState() == HostUp); BOOST_CHECK(host->GetState() == HostUp);
BOOST_CHECK(host->GetStateType() == StateTypeHard); BOOST_CHECK(host->GetStateType() == StateTypeHard);
BOOST_CHECK(host->GetCheckAttempt() == 1); BOOST_CHECK(host->GetCheckAttempt() == 1);
@ -126,7 +126,7 @@ BOOST_AUTO_TEST_CASE(host_2attempts)
CheckNotification(host, false); CheckNotification(host, false);
std::cout << "First check result (unknown)" << std::endl; std::cout << "First check result (unknown)" << std::endl;
host->ProcessCheckResult(MakeCheckResult(ServiceUnknown)); host->ProcessCheckResult(MakeCheckResult(ServiceUnknown), new StoppableWaitGroup());
BOOST_CHECK(host->GetState() == HostDown); BOOST_CHECK(host->GetState() == HostDown);
BOOST_CHECK(host->GetStateType() == StateTypeSoft); BOOST_CHECK(host->GetStateType() == StateTypeSoft);
BOOST_CHECK(host->GetCheckAttempt() == 1); BOOST_CHECK(host->GetCheckAttempt() == 1);
@ -134,7 +134,7 @@ BOOST_AUTO_TEST_CASE(host_2attempts)
CheckNotification(host, false); CheckNotification(host, false);
std::cout << "Second check result (critical)" << std::endl; std::cout << "Second check result (critical)" << std::endl;
host->ProcessCheckResult(MakeCheckResult(ServiceCritical)); host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
BOOST_CHECK(host->GetState() == HostDown); BOOST_CHECK(host->GetState() == HostDown);
BOOST_CHECK(host->GetStateType() == StateTypeHard); BOOST_CHECK(host->GetStateType() == StateTypeHard);
BOOST_CHECK(host->GetCheckAttempt() == 1); BOOST_CHECK(host->GetCheckAttempt() == 1);
@ -142,7 +142,7 @@ BOOST_AUTO_TEST_CASE(host_2attempts)
CheckNotification(host, true, NotificationProblem); CheckNotification(host, true, NotificationProblem);
std::cout << "Third check result (ok)" << std::endl; std::cout << "Third check result (ok)" << std::endl;
host->ProcessCheckResult(MakeCheckResult(ServiceOK)); host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
BOOST_CHECK(host->GetState() == HostUp); BOOST_CHECK(host->GetState() == HostUp);
BOOST_CHECK(host->GetStateType() == StateTypeHard); BOOST_CHECK(host->GetStateType() == StateTypeHard);
BOOST_CHECK(host->GetCheckAttempt() == 1); BOOST_CHECK(host->GetCheckAttempt() == 1);
@ -150,7 +150,7 @@ BOOST_AUTO_TEST_CASE(host_2attempts)
CheckNotification(host, true, NotificationRecovery); CheckNotification(host, true, NotificationRecovery);
std::cout << "Fourth check result (critical)" << std::endl; std::cout << "Fourth check result (critical)" << std::endl;
host->ProcessCheckResult(MakeCheckResult(ServiceCritical)); host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
BOOST_CHECK(host->GetState() == HostDown); BOOST_CHECK(host->GetState() == HostDown);
BOOST_CHECK(host->GetStateType() == StateTypeSoft); BOOST_CHECK(host->GetStateType() == StateTypeSoft);
BOOST_CHECK(host->GetCheckAttempt() == 1); BOOST_CHECK(host->GetCheckAttempt() == 1);
@ -158,7 +158,7 @@ BOOST_AUTO_TEST_CASE(host_2attempts)
CheckNotification(host, false); CheckNotification(host, false);
std::cout << "Fifth check result (ok)" << std::endl; std::cout << "Fifth check result (ok)" << std::endl;
host->ProcessCheckResult(MakeCheckResult(ServiceOK)); host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
BOOST_CHECK(host->GetState() == HostUp); BOOST_CHECK(host->GetState() == HostUp);
BOOST_CHECK(host->GetStateType() == StateTypeHard); BOOST_CHECK(host->GetStateType() == StateTypeHard);
BOOST_CHECK(host->GetCheckAttempt() == 1); BOOST_CHECK(host->GetCheckAttempt() == 1);
@ -191,7 +191,7 @@ BOOST_AUTO_TEST_CASE(host_3attempts)
CheckNotification(host, false); CheckNotification(host, false);
std::cout << "First check result (unknown)" << std::endl; std::cout << "First check result (unknown)" << std::endl;
host->ProcessCheckResult(MakeCheckResult(ServiceUnknown)); host->ProcessCheckResult(MakeCheckResult(ServiceUnknown), new StoppableWaitGroup());
BOOST_CHECK(host->GetState() == HostDown); BOOST_CHECK(host->GetState() == HostDown);
BOOST_CHECK(host->GetStateType() == StateTypeSoft); BOOST_CHECK(host->GetStateType() == StateTypeSoft);
BOOST_CHECK(host->GetCheckAttempt() == 1); BOOST_CHECK(host->GetCheckAttempt() == 1);
@ -199,7 +199,7 @@ BOOST_AUTO_TEST_CASE(host_3attempts)
CheckNotification(host, false); CheckNotification(host, false);
std::cout << "Second check result (critical)" << std::endl; std::cout << "Second check result (critical)" << std::endl;
host->ProcessCheckResult(MakeCheckResult(ServiceCritical)); host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
BOOST_CHECK(host->GetState() == HostDown); BOOST_CHECK(host->GetState() == HostDown);
BOOST_CHECK(host->GetStateType() == StateTypeSoft); BOOST_CHECK(host->GetStateType() == StateTypeSoft);
BOOST_CHECK(host->GetCheckAttempt() == 2); BOOST_CHECK(host->GetCheckAttempt() == 2);
@ -207,7 +207,7 @@ BOOST_AUTO_TEST_CASE(host_3attempts)
CheckNotification(host, false); CheckNotification(host, false);
std::cout << "Third check result (critical)" << std::endl; std::cout << "Third check result (critical)" << std::endl;
host->ProcessCheckResult(MakeCheckResult(ServiceCritical)); host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
BOOST_CHECK(host->GetState() == HostDown); BOOST_CHECK(host->GetState() == HostDown);
BOOST_CHECK(host->GetStateType() == StateTypeHard); BOOST_CHECK(host->GetStateType() == StateTypeHard);
BOOST_CHECK(host->GetCheckAttempt() == 1); BOOST_CHECK(host->GetCheckAttempt() == 1);
@ -215,7 +215,7 @@ BOOST_AUTO_TEST_CASE(host_3attempts)
CheckNotification(host, true, NotificationProblem); CheckNotification(host, true, NotificationProblem);
std::cout << "Fourth check result (ok)" << std::endl; std::cout << "Fourth check result (ok)" << std::endl;
host->ProcessCheckResult(MakeCheckResult(ServiceOK)); host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
BOOST_CHECK(host->GetState() == HostUp); BOOST_CHECK(host->GetState() == HostUp);
BOOST_CHECK(host->GetStateType() == StateTypeHard); BOOST_CHECK(host->GetStateType() == StateTypeHard);
BOOST_CHECK(host->GetCheckAttempt() == 1); BOOST_CHECK(host->GetCheckAttempt() == 1);
@ -223,7 +223,7 @@ BOOST_AUTO_TEST_CASE(host_3attempts)
CheckNotification(host, true, NotificationRecovery); CheckNotification(host, true, NotificationRecovery);
std::cout << "Fifth check result (critical)" << std::endl; std::cout << "Fifth check result (critical)" << std::endl;
host->ProcessCheckResult(MakeCheckResult(ServiceCritical)); host->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
BOOST_CHECK(host->GetState() == HostDown); BOOST_CHECK(host->GetState() == HostDown);
BOOST_CHECK(host->GetStateType() == StateTypeSoft); BOOST_CHECK(host->GetStateType() == StateTypeSoft);
BOOST_CHECK(host->GetCheckAttempt() == 1); BOOST_CHECK(host->GetCheckAttempt() == 1);
@ -231,7 +231,7 @@ BOOST_AUTO_TEST_CASE(host_3attempts)
CheckNotification(host, false); CheckNotification(host, false);
std::cout << "Sixth check result (ok)" << std::endl; std::cout << "Sixth check result (ok)" << std::endl;
host->ProcessCheckResult(MakeCheckResult(ServiceOK)); host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
BOOST_CHECK(host->GetState() == HostUp); BOOST_CHECK(host->GetState() == HostUp);
BOOST_CHECK(host->GetStateType() == StateTypeHard); BOOST_CHECK(host->GetStateType() == StateTypeHard);
BOOST_CHECK(host->GetCheckAttempt() == 1); BOOST_CHECK(host->GetCheckAttempt() == 1);
@ -264,7 +264,7 @@ BOOST_AUTO_TEST_CASE(service_1attempt)
CheckNotification(service, false); CheckNotification(service, false);
std::cout << "First check result (unknown)" << std::endl; std::cout << "First check result (unknown)" << std::endl;
service->ProcessCheckResult(MakeCheckResult(ServiceUnknown)); service->ProcessCheckResult(MakeCheckResult(ServiceUnknown), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == ServiceUnknown); BOOST_CHECK(service->GetState() == ServiceUnknown);
BOOST_CHECK(service->GetStateType() == StateTypeHard); BOOST_CHECK(service->GetStateType() == StateTypeHard);
BOOST_CHECK(service->GetCheckAttempt() == 1); BOOST_CHECK(service->GetCheckAttempt() == 1);
@ -272,7 +272,7 @@ BOOST_AUTO_TEST_CASE(service_1attempt)
CheckNotification(service, true, NotificationProblem); CheckNotification(service, true, NotificationProblem);
std::cout << "Second check result (ok)" << std::endl; std::cout << "Second check result (ok)" << std::endl;
service->ProcessCheckResult(MakeCheckResult(ServiceOK)); service->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == ServiceOK); BOOST_CHECK(service->GetState() == ServiceOK);
BOOST_CHECK(service->GetStateType() == StateTypeHard); BOOST_CHECK(service->GetStateType() == StateTypeHard);
BOOST_CHECK(service->GetCheckAttempt() == 1); BOOST_CHECK(service->GetCheckAttempt() == 1);
@ -280,7 +280,7 @@ BOOST_AUTO_TEST_CASE(service_1attempt)
CheckNotification(service, true, NotificationRecovery); CheckNotification(service, true, NotificationRecovery);
std::cout << "Third check result (critical)" << std::endl; std::cout << "Third check result (critical)" << std::endl;
service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == ServiceCritical); BOOST_CHECK(service->GetState() == ServiceCritical);
BOOST_CHECK(service->GetStateType() == StateTypeHard); BOOST_CHECK(service->GetStateType() == StateTypeHard);
BOOST_CHECK(service->GetCheckAttempt() == 1); BOOST_CHECK(service->GetCheckAttempt() == 1);
@ -288,7 +288,7 @@ BOOST_AUTO_TEST_CASE(service_1attempt)
CheckNotification(service, true, NotificationProblem); CheckNotification(service, true, NotificationProblem);
std::cout << "Fourth check result (ok)" << std::endl; std::cout << "Fourth check result (ok)" << std::endl;
service->ProcessCheckResult(MakeCheckResult(ServiceOK)); service->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == ServiceOK); BOOST_CHECK(service->GetState() == ServiceOK);
BOOST_CHECK(service->GetStateType() == StateTypeHard); BOOST_CHECK(service->GetStateType() == StateTypeHard);
BOOST_CHECK(service->GetCheckAttempt() == 1); BOOST_CHECK(service->GetCheckAttempt() == 1);
@ -321,7 +321,7 @@ BOOST_AUTO_TEST_CASE(service_2attempts)
CheckNotification(service, false); CheckNotification(service, false);
std::cout << "First check result (unknown)" << std::endl; std::cout << "First check result (unknown)" << std::endl;
service->ProcessCheckResult(MakeCheckResult(ServiceUnknown)); service->ProcessCheckResult(MakeCheckResult(ServiceUnknown), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == ServiceUnknown); BOOST_CHECK(service->GetState() == ServiceUnknown);
BOOST_CHECK(service->GetStateType() == StateTypeSoft); BOOST_CHECK(service->GetStateType() == StateTypeSoft);
BOOST_CHECK(service->GetCheckAttempt() == 1); BOOST_CHECK(service->GetCheckAttempt() == 1);
@ -329,7 +329,7 @@ BOOST_AUTO_TEST_CASE(service_2attempts)
CheckNotification(service, false); CheckNotification(service, false);
std::cout << "Second check result (critical)" << std::endl; std::cout << "Second check result (critical)" << std::endl;
service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == ServiceCritical); BOOST_CHECK(service->GetState() == ServiceCritical);
BOOST_CHECK(service->GetStateType() == StateTypeHard); BOOST_CHECK(service->GetStateType() == StateTypeHard);
BOOST_CHECK(service->GetCheckAttempt() == 1); BOOST_CHECK(service->GetCheckAttempt() == 1);
@ -337,7 +337,7 @@ BOOST_AUTO_TEST_CASE(service_2attempts)
CheckNotification(service, true, NotificationProblem); CheckNotification(service, true, NotificationProblem);
std::cout << "Third check result (ok)" << std::endl; std::cout << "Third check result (ok)" << std::endl;
service->ProcessCheckResult(MakeCheckResult(ServiceOK)); service->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == ServiceOK); BOOST_CHECK(service->GetState() == ServiceOK);
BOOST_CHECK(service->GetStateType() == StateTypeHard); BOOST_CHECK(service->GetStateType() == StateTypeHard);
BOOST_CHECK(service->GetCheckAttempt() == 1); BOOST_CHECK(service->GetCheckAttempt() == 1);
@ -345,7 +345,7 @@ BOOST_AUTO_TEST_CASE(service_2attempts)
CheckNotification(service, true, NotificationRecovery); CheckNotification(service, true, NotificationRecovery);
std::cout << "Fourth check result (critical)" << std::endl; std::cout << "Fourth check result (critical)" << std::endl;
service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == ServiceCritical); BOOST_CHECK(service->GetState() == ServiceCritical);
BOOST_CHECK(service->GetStateType() == StateTypeSoft); BOOST_CHECK(service->GetStateType() == StateTypeSoft);
BOOST_CHECK(service->GetCheckAttempt() == 1); BOOST_CHECK(service->GetCheckAttempt() == 1);
@ -353,7 +353,7 @@ BOOST_AUTO_TEST_CASE(service_2attempts)
CheckNotification(service, false); CheckNotification(service, false);
std::cout << "Fifth check result (ok)" << std::endl; std::cout << "Fifth check result (ok)" << std::endl;
service->ProcessCheckResult(MakeCheckResult(ServiceOK)); service->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == ServiceOK); BOOST_CHECK(service->GetState() == ServiceOK);
BOOST_CHECK(service->GetStateType() == StateTypeHard); BOOST_CHECK(service->GetStateType() == StateTypeHard);
BOOST_CHECK(service->GetCheckAttempt() == 1); BOOST_CHECK(service->GetCheckAttempt() == 1);
@ -386,7 +386,7 @@ BOOST_AUTO_TEST_CASE(service_3attempts)
CheckNotification(service, false); CheckNotification(service, false);
std::cout << "First check result (unknown)" << std::endl; std::cout << "First check result (unknown)" << std::endl;
service->ProcessCheckResult(MakeCheckResult(ServiceUnknown)); service->ProcessCheckResult(MakeCheckResult(ServiceUnknown), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == ServiceUnknown); BOOST_CHECK(service->GetState() == ServiceUnknown);
BOOST_CHECK(service->GetStateType() == StateTypeSoft); BOOST_CHECK(service->GetStateType() == StateTypeSoft);
BOOST_CHECK(service->GetCheckAttempt() == 1); BOOST_CHECK(service->GetCheckAttempt() == 1);
@ -394,7 +394,7 @@ BOOST_AUTO_TEST_CASE(service_3attempts)
CheckNotification(service, false); CheckNotification(service, false);
std::cout << "Second check result (critical)" << std::endl; std::cout << "Second check result (critical)" << std::endl;
service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == ServiceCritical); BOOST_CHECK(service->GetState() == ServiceCritical);
BOOST_CHECK(service->GetStateType() == StateTypeSoft); BOOST_CHECK(service->GetStateType() == StateTypeSoft);
BOOST_CHECK(service->GetCheckAttempt() == 2); BOOST_CHECK(service->GetCheckAttempt() == 2);
@ -402,7 +402,7 @@ BOOST_AUTO_TEST_CASE(service_3attempts)
CheckNotification(service, false); CheckNotification(service, false);
std::cout << "Third check result (critical)" << std::endl; std::cout << "Third check result (critical)" << std::endl;
service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == ServiceCritical); BOOST_CHECK(service->GetState() == ServiceCritical);
BOOST_CHECK(service->GetStateType() == StateTypeHard); BOOST_CHECK(service->GetStateType() == StateTypeHard);
BOOST_CHECK(service->GetCheckAttempt() == 1); BOOST_CHECK(service->GetCheckAttempt() == 1);
@ -410,7 +410,7 @@ BOOST_AUTO_TEST_CASE(service_3attempts)
CheckNotification(service, true, NotificationProblem); CheckNotification(service, true, NotificationProblem);
std::cout << "Fourth check result (ok)" << std::endl; std::cout << "Fourth check result (ok)" << std::endl;
service->ProcessCheckResult(MakeCheckResult(ServiceOK)); service->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == ServiceOK); BOOST_CHECK(service->GetState() == ServiceOK);
BOOST_CHECK(service->GetStateType() == StateTypeHard); BOOST_CHECK(service->GetStateType() == StateTypeHard);
BOOST_CHECK(service->GetCheckAttempt() == 1); BOOST_CHECK(service->GetCheckAttempt() == 1);
@ -418,7 +418,7 @@ BOOST_AUTO_TEST_CASE(service_3attempts)
CheckNotification(service, true, NotificationRecovery); CheckNotification(service, true, NotificationRecovery);
std::cout << "Fifth check result (critical)" << std::endl; std::cout << "Fifth check result (critical)" << std::endl;
service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == ServiceCritical); BOOST_CHECK(service->GetState() == ServiceCritical);
BOOST_CHECK(service->GetStateType() == StateTypeSoft); BOOST_CHECK(service->GetStateType() == StateTypeSoft);
BOOST_CHECK(service->GetCheckAttempt() == 1); BOOST_CHECK(service->GetCheckAttempt() == 1);
@ -426,7 +426,7 @@ BOOST_AUTO_TEST_CASE(service_3attempts)
CheckNotification(service, false); CheckNotification(service, false);
std::cout << "Sixth check result (ok)" << std::endl; std::cout << "Sixth check result (ok)" << std::endl;
service->ProcessCheckResult(MakeCheckResult(ServiceOK)); service->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == ServiceOK); BOOST_CHECK(service->GetState() == ServiceOK);
BOOST_CHECK(service->GetStateType() == StateTypeHard); BOOST_CHECK(service->GetStateType() == StateTypeHard);
BOOST_CHECK(service->GetCheckAttempt() == 1); BOOST_CHECK(service->GetCheckAttempt() == 1);
@ -470,7 +470,7 @@ BOOST_AUTO_TEST_CASE(host_flapping_notification)
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
ServiceState state = (i % 2 == 0 ? ServiceOK : ServiceCritical); ServiceState state = (i % 2 == 0 ? ServiceOK : ServiceCritical);
host->ProcessCheckResult(MakeCheckResult(state)); host->ProcessCheckResult(MakeCheckResult(state), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval); Utility::IncrementTime(timeStepInterval);
} }
@ -481,7 +481,7 @@ BOOST_AUTO_TEST_CASE(host_flapping_notification)
std::cout << "Now calm down..." << std::endl; std::cout << "Now calm down..." << std::endl;
for (int i = 0; i < 20; i++) { for (int i = 0; i < 20; i++) {
host->ProcessCheckResult(MakeCheckResult(ServiceOK)); host->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval); Utility::IncrementTime(timeStepInterval);
} }
@ -527,7 +527,7 @@ BOOST_AUTO_TEST_CASE(service_flapping_notification)
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
ServiceState state = (i % 2 == 0 ? ServiceOK : ServiceCritical); ServiceState state = (i % 2 == 0 ? ServiceOK : ServiceCritical);
service->ProcessCheckResult(MakeCheckResult(state)); service->ProcessCheckResult(MakeCheckResult(state), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval); Utility::IncrementTime(timeStepInterval);
} }
@ -540,7 +540,7 @@ BOOST_AUTO_TEST_CASE(service_flapping_notification)
std::cout << "Now calm down..." << std::endl; std::cout << "Now calm down..." << std::endl;
for (int i = 0; i < 20; i++) { for (int i = 0; i < 20; i++) {
service->ProcessCheckResult(MakeCheckResult(ServiceOK)); service->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval); Utility::IncrementTime(timeStepInterval);
} }
@ -585,7 +585,7 @@ BOOST_AUTO_TEST_CASE(service_flapping_problem_notifications)
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
ServiceState state = (i % 2 == 0 ? ServiceOK : ServiceCritical); ServiceState state = (i % 2 == 0 ? ServiceOK : ServiceCritical);
service->ProcessCheckResult(MakeCheckResult(state)); service->ProcessCheckResult(MakeCheckResult(state), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval); Utility::IncrementTime(timeStepInterval);
} }
@ -595,11 +595,11 @@ BOOST_AUTO_TEST_CASE(service_flapping_problem_notifications)
//Insert enough check results to get into hard problem state but staying flapping //Insert enough check results to get into hard problem state but staying flapping
service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval); Utility::IncrementTime(timeStepInterval);
service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval); Utility::IncrementTime(timeStepInterval);
service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval); Utility::IncrementTime(timeStepInterval);
@ -611,7 +611,7 @@ BOOST_AUTO_TEST_CASE(service_flapping_problem_notifications)
// Calm down // Calm down
while (service->IsFlapping()) { while (service->IsFlapping()) {
service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval); Utility::IncrementTime(timeStepInterval);
} }
@ -641,7 +641,7 @@ BOOST_AUTO_TEST_CASE(service_flapping_problem_notifications)
// Known failure, see #5713 // Known failure, see #5713
// CheckNotification(service, true, NotificationProblem); // CheckNotification(service, true, NotificationProblem);
service->ProcessCheckResult(MakeCheckResult(ServiceOK)); service->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval); Utility::IncrementTime(timeStepInterval);
// Known failure, see #5713 // Known failure, see #5713
@ -686,7 +686,7 @@ BOOST_AUTO_TEST_CASE(service_flapping_ok_into_bad)
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
ServiceState state = (i % 2 == 0 ? ServiceOK : ServiceCritical); ServiceState state = (i % 2 == 0 ? ServiceOK : ServiceCritical);
service->ProcessCheckResult(MakeCheckResult(state)); service->ProcessCheckResult(MakeCheckResult(state), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval); Utility::IncrementTime(timeStepInterval);
} }
@ -696,11 +696,11 @@ BOOST_AUTO_TEST_CASE(service_flapping_ok_into_bad)
//Insert enough check results to get into hard problem state but staying flapping //Insert enough check results to get into hard problem state but staying flapping
service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval); Utility::IncrementTime(timeStepInterval);
service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval); Utility::IncrementTime(timeStepInterval);
service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval); Utility::IncrementTime(timeStepInterval);
@ -712,13 +712,13 @@ BOOST_AUTO_TEST_CASE(service_flapping_ok_into_bad)
// Calm down // Calm down
while (service->IsFlapping()) { while (service->IsFlapping()) {
service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval); Utility::IncrementTime(timeStepInterval);
} }
CheckNotification(service, true, NotificationFlappingEnd); CheckNotification(service, true, NotificationFlappingEnd);
service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval); Utility::IncrementTime(timeStepInterval);
BOOST_CHECK(service->IsFlapping() == false); BOOST_CHECK(service->IsFlapping() == false);
@ -767,7 +767,7 @@ BOOST_AUTO_TEST_CASE(service_flapping_ok_over_bad_into_ok)
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
ServiceState state = (i % 2 == 0 ? ServiceOK : ServiceCritical); ServiceState state = (i % 2 == 0 ? ServiceOK : ServiceCritical);
service->ProcessCheckResult(MakeCheckResult(state)); service->ProcessCheckResult(MakeCheckResult(state), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval); Utility::IncrementTime(timeStepInterval);
} }
@ -777,11 +777,11 @@ BOOST_AUTO_TEST_CASE(service_flapping_ok_over_bad_into_ok)
//Insert enough check results to get into hard problem state but staying flapping //Insert enough check results to get into hard problem state but staying flapping
service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval); Utility::IncrementTime(timeStepInterval);
service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval); Utility::IncrementTime(timeStepInterval);
service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval); Utility::IncrementTime(timeStepInterval);
@ -793,13 +793,13 @@ BOOST_AUTO_TEST_CASE(service_flapping_ok_over_bad_into_ok)
// Calm down // Calm down
while (service->IsFlapping()) { while (service->IsFlapping()) {
service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); service->ProcessCheckResult(MakeCheckResult(ServiceCritical), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval); Utility::IncrementTime(timeStepInterval);
} }
CheckNotification(service, true, NotificationFlappingEnd); CheckNotification(service, true, NotificationFlappingEnd);
service->ProcessCheckResult(MakeCheckResult(ServiceOK)); service->ProcessCheckResult(MakeCheckResult(ServiceOK), new StoppableWaitGroup());
Utility::IncrementTime(timeStepInterval); Utility::IncrementTime(timeStepInterval);
BOOST_CHECK(service->IsFlapping() == false); BOOST_CHECK(service->IsFlapping() == false);
@ -894,7 +894,7 @@ BOOST_AUTO_TEST_CASE(suppressed_notification)
for (int i = 0; i < checkAttempts; i++) { for (int i = 0; i < checkAttempts; i++) {
std::cout << " ProcessCheckResult(" std::cout << " ProcessCheckResult("
<< Service::StateToString(initialState) << ")" << std::endl; << Service::StateToString(initialState) << ")" << std::endl;
service->ProcessCheckResult(MakeCheckResult(initialState)); service->ProcessCheckResult(MakeCheckResult(initialState), new StoppableWaitGroup());
} }
BOOST_CHECK(service->GetState() == initialState); BOOST_CHECK(service->GetState() == initialState);
@ -972,7 +972,7 @@ BOOST_AUTO_TEST_CASE(suppressed_notification)
// Process check results for the state sequence. // Process check results for the state sequence.
for (ServiceState s : sequence) { for (ServiceState s : sequence) {
std::cout << " ProcessCheckResult(" << Service::StateToString(s) << ")" << std::endl; std::cout << " ProcessCheckResult(" << Service::StateToString(s) << ")" << std::endl;
service->ProcessCheckResult(MakeCheckResult(s)); service->ProcessCheckResult(MakeCheckResult(s), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == s); BOOST_CHECK(service->GetState() == s);
if (checkAttempts == 1) { if (checkAttempts == 1) {
BOOST_CHECK(service->GetStateType() == StateTypeHard); BOOST_CHECK(service->GetStateType() == StateTypeHard);
@ -1002,7 +1002,7 @@ BOOST_AUTO_TEST_CASE(suppressed_notification)
for (int i = 0; i < checkAttempts && service->GetStateType() == StateTypeSoft; i++) { for (int i = 0; i < checkAttempts && service->GetStateType() == StateTypeSoft; i++) {
std::cout << " ProcessCheckResult(" << Service::StateToString(sequence.back()) << ")" std::cout << " ProcessCheckResult(" << Service::StateToString(sequence.back()) << ")"
<< std::endl; << std::endl;
service->ProcessCheckResult(MakeCheckResult(sequence.back())); service->ProcessCheckResult(MakeCheckResult(sequence.back()), new StoppableWaitGroup());
BOOST_CHECK(service->GetState() == sequence.back()); BOOST_CHECK(service->GetState() == sequence.back());
} }
} }

View File

@ -15,7 +15,7 @@ String LivestatusQueryHelper(const std::vector<String>& lines)
std::stringstream stream; std::stringstream stream;
StdioStream::Ptr sstream = new StdioStream(&stream, false); StdioStream::Ptr sstream = new StdioStream(&stream, false);
query->Execute(sstream); query->Execute(new StoppableWaitGroup(), sstream);
String output; String output;
String result; String result;