Skip to content

Commit

Permalink
IfwApiCheckTask: Process final cr in the global thread pool
Browse files Browse the repository at this point in the history
  • Loading branch information
yhabteab committed Aug 30, 2024
1 parent c052fa0 commit 0aa76ff
Showing 1 changed file with 35 additions and 52 deletions.
87 changes: 35 additions & 52 deletions lib/methods/ifwapichecktask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,16 +89,6 @@ inline IfwResultHandlerFunc getIfwResultHandlerFunc(const Checkable::Ptr& checka
};
}

static void ReportIfwCheckResult(
boost::asio::yield_context yc,const Value& cmdLine, const String& output, double start, const IfwResultHandlerFunc& resultHandler
)
{
double end = Utility::GetTime();
CpuBoundWork cbw (yc);

resultHandler(cmdLine, output, start, end, 3, nullptr);
}

static const char* GetUnderstandableError(const std::exception& ex)
{
auto se (dynamic_cast<const boost::system::system_error*>(&ex));
Expand All @@ -118,16 +108,23 @@ static void DoIfwNetIo(
{
namespace http = boost::beast::http;

auto asyncReportResult = [start, cmdLine, resultHandler = std::move(resultHandler)](
const String& output, double end, int exitcode = 3, const Array::Ptr& perfdata = nullptr
) {
Utility::QueueAsyncCallback([cmdLine, output, start, end, exitcode, perfdata, resultHandler = std::move(resultHandler)]() {
resultHandler(cmdLine, output, start, end, exitcode, perfdata);
});
};

boost::beast::flat_buffer buf;
http::response<http::string_body> resp;

try {
Connect(conn.lowest_layer(), psHost, psPort, yc);
} catch (const std::exception& ex) {
ReportIfwCheckResult(
yc, cmdLine,
asyncReportResult(
"Can't connect to IfW API on host '" + psHost + "' port '" + psPort + "': " + GetUnderstandableError(ex),
start, resultHandler
Utility::GetTime()
);
return;
}
Expand All @@ -137,11 +134,9 @@ static void DoIfwNetIo(
try {
sslConn.async_handshake(conn.next_layer().client, yc);
} catch (const std::exception& ex) {
ReportIfwCheckResult(
yc, cmdLine,
"TLS handshake with IfW API on host '" + psHost + "' (SNI: '" + san
+ "') port '" + psPort + "' failed: " + GetUnderstandableError(ex),
start, resultHandler
asyncReportResult(
"TLS handshake with IfW API on host '" + psHost + "' (SNI: '" + san+ "') port '" + psPort + "' failed: " + GetUnderstandableError(ex),
Utility::GetTime()
);
return;
}
Expand All @@ -155,11 +150,10 @@ static void DoIfwNetIo(
} catch (const std::exception&) {
}

ReportIfwCheckResult(
yc, cmdLine,
asyncReportResult(
"Certificate validation failed for IfW API on host '" + psHost + "' (SNI: '" + san + "'; CN: "
+ (cn.IsString() ? "'" + cn + "'" : "N/A") + ") port '" + psPort + "': " + sslConn.GetVerifyError(),
start, resultHandler
Utility::GetTime()
);
return;
}
Expand All @@ -168,21 +162,19 @@ static void DoIfwNetIo(
http::async_write(conn, req, yc);
conn.async_flush(yc);
} catch (const std::exception& ex) {
ReportIfwCheckResult(
yc, cmdLine,
asyncReportResult(
"Can't send HTTP request to IfW API on host '" + psHost + "' port '" + psPort + "': " + GetUnderstandableError(ex),
start, resultHandler
Utility::GetTime()
);
return;
}

try {
http::async_read(conn, buf, resp, yc);
} catch (const std::exception& ex) {
ReportIfwCheckResult(
yc, cmdLine,
asyncReportResult(
"Can't read HTTP response from IfW API on host '" + psHost + "' port '" + psPort + "': " + GetUnderstandableError(ex),
start, resultHandler
Utility::GetTime()
);
return;
}
Expand All @@ -194,44 +186,39 @@ static void DoIfwNetIo(
sslConn.async_shutdown(yc[ec]);
}

CpuBoundWork cbw (yc);
Value jsonRoot;

try {
jsonRoot = JsonDecode(resp.body());
} catch (const std::exception& ex) {
resultHandler(
cmdLine,"Got bad JSON from IfW API on host '" + psHost + "' port '" + psPort + "': " + ex.what(), start, end, 3, nullptr);
asyncReportResult("Got bad JSON from IfW API on host '" + psHost + "' port '" + psPort + "': " + ex.what(), end);
return;
}

if (!jsonRoot.IsObjectType<Dictionary>()) {
resultHandler(
cmdLine,
asyncReportResult(
"Got JSON, but not an object, from IfW API on host '"+ psHost + "' port '" + psPort + "': " + JsonEncode(jsonRoot),
start, end, 3, nullptr
end
);
return;
}

Value jsonBranch;

if (!Dictionary::Ptr(jsonRoot)->Get(psCommand, &jsonBranch)) {
resultHandler(
cmdLine,
asyncReportResult(
"Missing ." + psCommand + " in JSON object from IfW API on host '"
+ psHost + "' port '" + psPort + "': " + JsonEncode(jsonRoot),
start, end, 3, nullptr
end
);
return;
}

if (!jsonBranch.IsObjectType<Dictionary>()) {
resultHandler(
cmdLine,
asyncReportResult(
"." + psCommand + " in JSON from IfW API on host '"
+ psHost + "' port '" + psPort + "' is not an object: " + JsonEncode(jsonBranch),
start, end, 3, nullptr
end
);
return;
}
Expand All @@ -241,11 +228,10 @@ static void DoIfwNetIo(
Value exitcode;

if (!result->Get("exitcode", &exitcode)) {
resultHandler(
cmdLine,
asyncReportResult(
"Missing ." + psCommand + ".exitcode in JSON object from IfW API on host '"
+ psHost + "' port '" + psPort + "': " + JsonEncode(result),
start, end, 3, nullptr
end
);
return;
}
Expand All @@ -254,11 +240,10 @@ static void DoIfwNetIo(
static const auto exitcodeList (Array::FromSet(exitcodes)->Join(", "));

if (!exitcode.IsNumber() || exitcodes.find(exitcode) == exitcodes.end()) {
resultHandler(
cmdLine,
asyncReportResult(
"Got bad exitcode " + JsonEncode(exitcode) + " from IfW API on host '" + psHost + "' port '" + psPort
+ "', expected one of: " + exitcodeList,
start, end, 3, nullptr
end
);
return;
}
Expand All @@ -269,11 +254,10 @@ static void DoIfwNetIo(
try {
perfdata = perfdataVal;
} catch (const std::exception&) {
resultHandler(
cmdLine,
asyncReportResult(
"Got bad perfdata " + JsonEncode(perfdataVal) + " from IfW API on host '"
+ psHost + "' port '" + psPort + "', expected an array",
start, end, 3, nullptr
end
);
return;
}
Expand All @@ -283,18 +267,17 @@ static void DoIfwNetIo(

for (auto& pv : perfdata) {
if (!pv.IsString()) {
resultHandler(
cmdLine,
asyncReportResult(
"Got bad perfdata value " + JsonEncode(perfdata) + " from IfW API on host '"
+ psHost + "' port '" + psPort + "', expected an array of strings",
start, end, 3, nullptr
end
);
return;
}
}
}

resultHandler(cmdLine, result->Get("checkresult"), start, end, exitcode, perfdata);
asyncReportResult(result->Get("checkresult"), end, exitcode, perfdata);
}

void IfwApiCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr,
Expand Down

0 comments on commit 0aa76ff

Please sign in to comment.