mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-25 14:44:32 +02:00
Use WaitGroup to wait for or abort HTTP requests
The wait group gets passed to HttpServerConnection, then down to the HttpHandlers. For those handlers that modify the program state, the wait group is locked so ApiListener will wait on Stop() for the request to complete. If the request iterates over config objects, a further check on the state of the wait group is added to abort early and not delay program shutdown. In that case, 503 responses will be sent to the client. Additionally, in HttpServerConnection, no further requests than the one already started will be allowed once the wait group is joining.
This commit is contained in:
parent
33777f6f3f
commit
82bb636d2b
@ -16,6 +16,7 @@ thread_local ApiUser::Ptr ActionsHandler::AuthenticatedApiUser;
|
|||||||
REGISTER_URLHANDLER("/v1/actions", ActionsHandler);
|
REGISTER_URLHANDLER("/v1/actions", ActionsHandler);
|
||||||
|
|
||||||
bool ActionsHandler::HandleRequest(
|
bool ActionsHandler::HandleRequest(
|
||||||
|
const WaitGroup::Ptr& waitGroup,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
@ -88,7 +89,28 @@ bool ActionsHandler::HandleRequest(
|
|||||||
if (params)
|
if (params)
|
||||||
verbose = HttpUtility::GetLastParameter(params, "verbose");
|
verbose = HttpUtility::GetLastParameter(params, "verbose");
|
||||||
|
|
||||||
|
std::shared_lock wgLock{*waitGroup, std::try_to_lock};
|
||||||
|
if (!wgLock) {
|
||||||
|
HttpUtility::SendJsonError(response, params, 503, "Shutting down.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
for (ConfigObject::Ptr obj : objs) {
|
for (ConfigObject::Ptr obj : objs) {
|
||||||
|
if (!waitGroup->IsLockable()) {
|
||||||
|
if (wgLock) {
|
||||||
|
wgLock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
results.emplace_back(new Dictionary({
|
||||||
|
{ "type", obj->GetReflectionType()->GetName() },
|
||||||
|
{ "name", obj->GetName() },
|
||||||
|
{ "code", 503 },
|
||||||
|
{ "status", "Action skipped: Shutting down."}
|
||||||
|
}));
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
results.emplace_back(action->Invoke(obj, params));
|
results.emplace_back(action->Invoke(obj, params));
|
||||||
} catch (const std::exception& ex) {
|
} catch (const std::exception& ex) {
|
||||||
|
@ -16,6 +16,7 @@ public:
|
|||||||
static thread_local ApiUser::Ptr AuthenticatedApiUser;
|
static thread_local ApiUser::Ptr AuthenticatedApiUser;
|
||||||
|
|
||||||
bool HandleRequest(
|
bool HandleRequest(
|
||||||
|
const WaitGroup::Ptr& waitGroup,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
|
@ -917,7 +917,7 @@ void ApiListener::NewClientHandlerInternal(
|
|||||||
} else {
|
} else {
|
||||||
Log(LogNotice, "ApiListener", "New HTTP client");
|
Log(LogNotice, "ApiListener", "New HTTP client");
|
||||||
|
|
||||||
HttpServerConnection::Ptr aclient = new HttpServerConnection(identity, verify_ok, client);
|
HttpServerConnection::Ptr aclient = new HttpServerConnection(m_WaitGroup, identity, verify_ok, client);
|
||||||
AddHttpClient(aclient);
|
AddHttpClient(aclient);
|
||||||
aclient->Start();
|
aclient->Start();
|
||||||
shutdownSslConn.Cancel();
|
shutdownSslConn.Cancel();
|
||||||
|
@ -14,6 +14,7 @@ using namespace icinga;
|
|||||||
REGISTER_URLHANDLER("/v1/config/files", ConfigFilesHandler);
|
REGISTER_URLHANDLER("/v1/config/files", ConfigFilesHandler);
|
||||||
|
|
||||||
bool ConfigFilesHandler::HandleRequest(
|
bool ConfigFilesHandler::HandleRequest(
|
||||||
|
const WaitGroup::Ptr&,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
|
@ -14,6 +14,7 @@ public:
|
|||||||
DECLARE_PTR_TYPEDEFS(ConfigFilesHandler);
|
DECLARE_PTR_TYPEDEFS(ConfigFilesHandler);
|
||||||
|
|
||||||
bool HandleRequest(
|
bool HandleRequest(
|
||||||
|
const WaitGroup::Ptr& waitGroup,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
|
@ -11,6 +11,7 @@ using namespace icinga;
|
|||||||
REGISTER_URLHANDLER("/v1/config/packages", ConfigPackagesHandler);
|
REGISTER_URLHANDLER("/v1/config/packages", ConfigPackagesHandler);
|
||||||
|
|
||||||
bool ConfigPackagesHandler::HandleRequest(
|
bool ConfigPackagesHandler::HandleRequest(
|
||||||
|
const WaitGroup::Ptr&,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
|
@ -14,6 +14,7 @@ public:
|
|||||||
DECLARE_PTR_TYPEDEFS(ConfigPackagesHandler);
|
DECLARE_PTR_TYPEDEFS(ConfigPackagesHandler);
|
||||||
|
|
||||||
bool HandleRequest(
|
bool HandleRequest(
|
||||||
|
const WaitGroup::Ptr& waitGroup,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
|
@ -15,6 +15,7 @@ REGISTER_URLHANDLER("/v1/config/stages", ConfigStagesHandler);
|
|||||||
std::atomic<bool> ConfigStagesHandler::m_RunningPackageUpdates (false);
|
std::atomic<bool> ConfigStagesHandler::m_RunningPackageUpdates (false);
|
||||||
|
|
||||||
bool ConfigStagesHandler::HandleRequest(
|
bool ConfigStagesHandler::HandleRequest(
|
||||||
|
const WaitGroup::Ptr&,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
|
@ -15,6 +15,7 @@ public:
|
|||||||
DECLARE_PTR_TYPEDEFS(ConfigStagesHandler);
|
DECLARE_PTR_TYPEDEFS(ConfigStagesHandler);
|
||||||
|
|
||||||
bool HandleRequest(
|
bool HandleRequest(
|
||||||
|
const WaitGroup::Ptr& waitGroup,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
|
@ -54,6 +54,7 @@ static void EnsureFrameCleanupTimer()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ConsoleHandler::HandleRequest(
|
bool ConsoleHandler::HandleRequest(
|
||||||
|
const WaitGroup::Ptr&,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
|
@ -23,6 +23,7 @@ public:
|
|||||||
DECLARE_PTR_TYPEDEFS(ConsoleHandler);
|
DECLARE_PTR_TYPEDEFS(ConsoleHandler);
|
||||||
|
|
||||||
bool HandleRequest(
|
bool HandleRequest(
|
||||||
|
const WaitGroup::Ptr& waitGroup,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
|
@ -16,6 +16,7 @@ using namespace icinga;
|
|||||||
REGISTER_URLHANDLER("/v1/objects", CreateObjectHandler);
|
REGISTER_URLHANDLER("/v1/objects", CreateObjectHandler);
|
||||||
|
|
||||||
bool CreateObjectHandler::HandleRequest(
|
bool CreateObjectHandler::HandleRequest(
|
||||||
|
const WaitGroup::Ptr& waitGroup,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
@ -102,6 +103,12 @@ bool CreateObjectHandler::HandleRequest(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_lock wgLock{*waitGroup, std::try_to_lock};
|
||||||
|
if (!wgLock) {
|
||||||
|
HttpUtility::SendJsonError(response, params, 503, "Shutting down.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Object creation can cause multiple errors and optionally diagnostic information.
|
/* Object creation can cause multiple errors and optionally diagnostic information.
|
||||||
* We can't use SendJsonError() here.
|
* We can't use SendJsonError() here.
|
||||||
*/
|
*/
|
||||||
|
@ -14,6 +14,7 @@ public:
|
|||||||
DECLARE_PTR_TYPEDEFS(CreateObjectHandler);
|
DECLARE_PTR_TYPEDEFS(CreateObjectHandler);
|
||||||
|
|
||||||
bool HandleRequest(
|
bool HandleRequest(
|
||||||
|
const WaitGroup::Ptr& waitGroup,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
|
@ -16,6 +16,7 @@ using namespace icinga;
|
|||||||
REGISTER_URLHANDLER("/v1/objects", DeleteObjectHandler);
|
REGISTER_URLHANDLER("/v1/objects", DeleteObjectHandler);
|
||||||
|
|
||||||
bool DeleteObjectHandler::HandleRequest(
|
bool DeleteObjectHandler::HandleRequest(
|
||||||
|
const WaitGroup::Ptr& waitGroup,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
@ -78,7 +79,30 @@ bool DeleteObjectHandler::HandleRequest(
|
|||||||
|
|
||||||
bool success = true;
|
bool success = true;
|
||||||
|
|
||||||
|
std::shared_lock wgLock{*waitGroup, std::try_to_lock};
|
||||||
|
if (!wgLock) {
|
||||||
|
HttpUtility::SendJsonError(response, params, 503, "Shutting down.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
for (ConfigObject::Ptr obj : objs) {
|
for (ConfigObject::Ptr obj : objs) {
|
||||||
|
if (!waitGroup->IsLockable()) {
|
||||||
|
if (wgLock) {
|
||||||
|
wgLock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
results.emplace_back(new Dictionary({
|
||||||
|
{ "type", type->GetName() },
|
||||||
|
{ "name", obj->GetName() },
|
||||||
|
{ "code", 503 },
|
||||||
|
{ "status", "Action skipped: Shutting down."}
|
||||||
|
}));
|
||||||
|
|
||||||
|
success = false;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
int code;
|
int code;
|
||||||
String status;
|
String status;
|
||||||
Array::Ptr errors = new Array();
|
Array::Ptr errors = new Array();
|
||||||
|
@ -14,6 +14,7 @@ public:
|
|||||||
DECLARE_PTR_TYPEDEFS(DeleteObjectHandler);
|
DECLARE_PTR_TYPEDEFS(DeleteObjectHandler);
|
||||||
|
|
||||||
bool HandleRequest(
|
bool HandleRequest(
|
||||||
|
const WaitGroup::Ptr& waitGroup,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
|
@ -40,6 +40,7 @@ const std::map<String, EventType> l_EventTypes ({
|
|||||||
const String l_ApiQuery ("<API query>");
|
const String l_ApiQuery ("<API query>");
|
||||||
|
|
||||||
bool EventsHandler::HandleRequest(
|
bool EventsHandler::HandleRequest(
|
||||||
|
const WaitGroup::Ptr&,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
|
@ -15,6 +15,7 @@ public:
|
|||||||
DECLARE_PTR_TYPEDEFS(EventsHandler);
|
DECLARE_PTR_TYPEDEFS(EventsHandler);
|
||||||
|
|
||||||
bool HandleRequest(
|
bool HandleRequest(
|
||||||
|
const WaitGroup::Ptr& waitGroup,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
|
@ -47,6 +47,7 @@ void HttpHandler::Register(const Url::Ptr& url, const HttpHandler::Ptr& handler)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void HttpHandler::ProcessRequest(
|
void HttpHandler::ProcessRequest(
|
||||||
|
const WaitGroup::Ptr& waitGroup,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
@ -108,7 +109,7 @@ void HttpHandler::ProcessRequest(
|
|||||||
*/
|
*/
|
||||||
try {
|
try {
|
||||||
for (const HttpHandler::Ptr& handler : handlers) {
|
for (const HttpHandler::Ptr& handler : handlers) {
|
||||||
if (handler->HandleRequest(stream, user, request, url, response, params, yc, server)) {
|
if (handler->HandleRequest(waitGroup, stream, user, request, url, response, params, yc, server)) {
|
||||||
processed = true;
|
processed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ public:
|
|||||||
DECLARE_PTR_TYPEDEFS(HttpHandler);
|
DECLARE_PTR_TYPEDEFS(HttpHandler);
|
||||||
|
|
||||||
virtual bool HandleRequest(
|
virtual bool HandleRequest(
|
||||||
|
const WaitGroup::Ptr& waitGroup,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
@ -39,6 +40,7 @@ public:
|
|||||||
|
|
||||||
static void Register(const Url::Ptr& url, const HttpHandler::Ptr& handler);
|
static void Register(const Url::Ptr& url, const HttpHandler::Ptr& handler);
|
||||||
static void ProcessRequest(
|
static void ProcessRequest(
|
||||||
|
const WaitGroup::Ptr& waitGroup,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
|
@ -35,13 +35,13 @@ using namespace icinga;
|
|||||||
|
|
||||||
auto const l_ServerHeader ("Icinga/" + Application::GetAppVersion());
|
auto const l_ServerHeader ("Icinga/" + Application::GetAppVersion());
|
||||||
|
|
||||||
HttpServerConnection::HttpServerConnection(const String& identity, bool authenticated, const Shared<AsioTlsStream>::Ptr& stream)
|
HttpServerConnection::HttpServerConnection(const WaitGroup::Ptr& waitGroup, const String& identity, bool authenticated, const Shared<AsioTlsStream>::Ptr& stream)
|
||||||
: HttpServerConnection(identity, authenticated, stream, IoEngine::Get().GetIoContext())
|
: HttpServerConnection(waitGroup, identity, authenticated, stream, IoEngine::Get().GetIoContext())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpServerConnection::HttpServerConnection(const String& identity, bool authenticated, const Shared<AsioTlsStream>::Ptr& stream, boost::asio::io_context& io)
|
HttpServerConnection::HttpServerConnection(const WaitGroup::Ptr& waitGroup, const String& identity, bool authenticated, const Shared<AsioTlsStream>::Ptr& stream, boost::asio::io_context& io)
|
||||||
: m_Stream(stream), m_Seen(Utility::GetTime()), m_IoStrand(io), m_ShuttingDown(false), m_HasStartedStreaming(false),
|
: m_WaitGroup(waitGroup), m_Stream(stream), m_Seen(Utility::GetTime()), m_IoStrand(io), m_ShuttingDown(false), m_HasStartedStreaming(false),
|
||||||
m_CheckLivenessTimer(io)
|
m_CheckLivenessTimer(io)
|
||||||
{
|
{
|
||||||
if (authenticated) {
|
if (authenticated) {
|
||||||
@ -419,6 +419,7 @@ bool ProcessRequest(
|
|||||||
boost::beast::http::response<boost::beast::http::string_body>& response,
|
boost::beast::http::response<boost::beast::http::string_body>& response,
|
||||||
HttpServerConnection& server,
|
HttpServerConnection& server,
|
||||||
bool& hasStartedStreaming,
|
bool& hasStartedStreaming,
|
||||||
|
const WaitGroup::Ptr& waitGroup,
|
||||||
std::chrono::steady_clock::duration& cpuBoundWorkTime,
|
std::chrono::steady_clock::duration& cpuBoundWorkTime,
|
||||||
boost::asio::yield_context& yc
|
boost::asio::yield_context& yc
|
||||||
)
|
)
|
||||||
@ -431,7 +432,7 @@ bool ProcessRequest(
|
|||||||
CpuBoundWork handlingRequest (yc);
|
CpuBoundWork handlingRequest (yc);
|
||||||
cpuBoundWorkTime = std::chrono::steady_clock::now() - start;
|
cpuBoundWorkTime = std::chrono::steady_clock::now() - start;
|
||||||
|
|
||||||
HttpHandler::ProcessRequest(stream, authenticatedUser, request, response, yc, server);
|
HttpHandler::ProcessRequest(waitGroup, stream, authenticatedUser, request, response, yc, server);
|
||||||
} catch (const std::exception& ex) {
|
} catch (const std::exception& ex) {
|
||||||
if (hasStartedStreaming) {
|
if (hasStartedStreaming) {
|
||||||
return false;
|
return false;
|
||||||
@ -477,7 +478,7 @@ void HttpServerConnection::ProcessMessages(boost::asio::yield_context yc)
|
|||||||
*/
|
*/
|
||||||
beast::flat_buffer buf;
|
beast::flat_buffer buf;
|
||||||
|
|
||||||
for (;;) {
|
while (m_WaitGroup->IsLockable()) {
|
||||||
m_Seen = Utility::GetTime();
|
m_Seen = Utility::GetTime();
|
||||||
|
|
||||||
http::parser<true, http::string_body> parser;
|
http::parser<true, http::string_body> parser;
|
||||||
@ -548,7 +549,7 @@ void HttpServerConnection::ProcessMessages(boost::asio::yield_context yc)
|
|||||||
|
|
||||||
m_Seen = std::numeric_limits<decltype(m_Seen)>::max();
|
m_Seen = std::numeric_limits<decltype(m_Seen)>::max();
|
||||||
|
|
||||||
if (!ProcessRequest(*m_Stream, request, authenticatedUser, response, *this, m_HasStartedStreaming, cpuBoundWorkTime, yc)) {
|
if (!ProcessRequest(*m_Stream, request, authenticatedUser, response, *this, m_HasStartedStreaming, m_WaitGroup, cpuBoundWorkTime, yc)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "remote/apiuser.hpp"
|
#include "remote/apiuser.hpp"
|
||||||
#include "base/string.hpp"
|
#include "base/string.hpp"
|
||||||
#include "base/tlsstream.hpp"
|
#include "base/tlsstream.hpp"
|
||||||
|
#include "base/wait-group.hpp"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <boost/asio/deadline_timer.hpp>
|
#include <boost/asio/deadline_timer.hpp>
|
||||||
#include <boost/asio/io_context.hpp>
|
#include <boost/asio/io_context.hpp>
|
||||||
@ -25,14 +26,15 @@ class HttpServerConnection final : public Object
|
|||||||
public:
|
public:
|
||||||
DECLARE_PTR_TYPEDEFS(HttpServerConnection);
|
DECLARE_PTR_TYPEDEFS(HttpServerConnection);
|
||||||
|
|
||||||
HttpServerConnection(const String& identity, bool authenticated, const Shared<AsioTlsStream>::Ptr& stream);
|
HttpServerConnection(const WaitGroup::Ptr& waitGroup, const String& identity, bool authenticated,
|
||||||
|
const Shared<AsioTlsStream>::Ptr& stream);
|
||||||
|
|
||||||
void Start();
|
void Start();
|
||||||
void StartStreaming();
|
void StartStreaming();
|
||||||
|
|
||||||
bool Disconnected();
|
bool Disconnected();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
WaitGroup::Ptr m_WaitGroup;
|
||||||
ApiUser::Ptr m_ApiUser;
|
ApiUser::Ptr m_ApiUser;
|
||||||
Shared<AsioTlsStream>::Ptr m_Stream;
|
Shared<AsioTlsStream>::Ptr m_Stream;
|
||||||
double m_Seen;
|
double m_Seen;
|
||||||
@ -42,7 +44,8 @@ private:
|
|||||||
bool m_HasStartedStreaming;
|
bool m_HasStartedStreaming;
|
||||||
boost::asio::deadline_timer m_CheckLivenessTimer;
|
boost::asio::deadline_timer m_CheckLivenessTimer;
|
||||||
|
|
||||||
HttpServerConnection(const String& identity, bool authenticated, const Shared<AsioTlsStream>::Ptr& stream, boost::asio::io_context& io);
|
HttpServerConnection(const WaitGroup::Ptr& waitGroup, const String& identity, bool authenticated,
|
||||||
|
const Shared<AsioTlsStream>::Ptr& stream, boost::asio::io_context& io);
|
||||||
|
|
||||||
void Disconnect(boost::asio::yield_context yc);
|
void Disconnect(boost::asio::yield_context yc);
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ using namespace icinga;
|
|||||||
REGISTER_URLHANDLER("/", InfoHandler);
|
REGISTER_URLHANDLER("/", InfoHandler);
|
||||||
|
|
||||||
bool InfoHandler::HandleRequest(
|
bool InfoHandler::HandleRequest(
|
||||||
|
const WaitGroup::Ptr&,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
|
@ -14,6 +14,7 @@ public:
|
|||||||
DECLARE_PTR_TYPEDEFS(InfoHandler);
|
DECLARE_PTR_TYPEDEFS(InfoHandler);
|
||||||
|
|
||||||
bool HandleRequest(
|
bool HandleRequest(
|
||||||
|
const WaitGroup::Ptr& waitGroup,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
|
@ -18,6 +18,7 @@ using namespace icinga;
|
|||||||
REGISTER_URLHANDLER("/v1/debug/malloc_info", MallocInfoHandler);
|
REGISTER_URLHANDLER("/v1/debug/malloc_info", MallocInfoHandler);
|
||||||
|
|
||||||
bool MallocInfoHandler::HandleRequest(
|
bool MallocInfoHandler::HandleRequest(
|
||||||
|
const WaitGroup::Ptr&,
|
||||||
AsioTlsStream&,
|
AsioTlsStream&,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
|
@ -13,6 +13,7 @@ public:
|
|||||||
DECLARE_PTR_TYPEDEFS(MallocInfoHandler);
|
DECLARE_PTR_TYPEDEFS(MallocInfoHandler);
|
||||||
|
|
||||||
bool HandleRequest(
|
bool HandleRequest(
|
||||||
|
const WaitGroup::Ptr& waitGroup,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
|
@ -14,6 +14,7 @@ using namespace icinga;
|
|||||||
REGISTER_URLHANDLER("/v1/objects", ModifyObjectHandler);
|
REGISTER_URLHANDLER("/v1/objects", ModifyObjectHandler);
|
||||||
|
|
||||||
bool ModifyObjectHandler::HandleRequest(
|
bool ModifyObjectHandler::HandleRequest(
|
||||||
|
const WaitGroup::Ptr& waitGroup,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
@ -104,12 +105,31 @@ bool ModifyObjectHandler::HandleRequest(
|
|||||||
|
|
||||||
ArrayData results;
|
ArrayData results;
|
||||||
|
|
||||||
|
std::shared_lock wgLock{*waitGroup, std::try_to_lock};
|
||||||
|
if (!wgLock) {
|
||||||
|
HttpUtility::SendJsonError(response, params, 503, "Shutting down.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
for (ConfigObject::Ptr obj : objs) {
|
for (ConfigObject::Ptr obj : objs) {
|
||||||
Dictionary::Ptr result1 = new Dictionary();
|
Dictionary::Ptr result1 = new Dictionary();
|
||||||
|
|
||||||
result1->Set("type", type->GetName());
|
result1->Set("type", type->GetName());
|
||||||
result1->Set("name", obj->GetName());
|
result1->Set("name", obj->GetName());
|
||||||
|
|
||||||
|
if (!waitGroup->IsLockable()) {
|
||||||
|
if (wgLock) {
|
||||||
|
wgLock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
result1->Set("code", 503);
|
||||||
|
result1->Set("status", "Action skipped: Shutting down.");
|
||||||
|
|
||||||
|
results.emplace_back(std::move(result1));
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
String key;
|
String key;
|
||||||
|
|
||||||
// Lock the object name of the given type to prevent from being modified/deleted concurrently.
|
// Lock the object name of the given type to prevent from being modified/deleted concurrently.
|
||||||
|
@ -14,6 +14,7 @@ public:
|
|||||||
DECLARE_PTR_TYPEDEFS(ModifyObjectHandler);
|
DECLARE_PTR_TYPEDEFS(ModifyObjectHandler);
|
||||||
|
|
||||||
bool HandleRequest(
|
bool HandleRequest(
|
||||||
|
const WaitGroup::Ptr& waitGroup,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
|
@ -89,6 +89,7 @@ Dictionary::Ptr ObjectQueryHandler::SerializeObjectAttrs(const Object::Ptr& obje
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ObjectQueryHandler::HandleRequest(
|
bool ObjectQueryHandler::HandleRequest(
|
||||||
|
const WaitGroup::Ptr&,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
|
@ -14,6 +14,7 @@ public:
|
|||||||
DECLARE_PTR_TYPEDEFS(ObjectQueryHandler);
|
DECLARE_PTR_TYPEDEFS(ObjectQueryHandler);
|
||||||
|
|
||||||
bool HandleRequest(
|
bool HandleRequest(
|
||||||
|
const WaitGroup::Ptr& waitGroup,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
|
@ -69,6 +69,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
bool StatusHandler::HandleRequest(
|
bool StatusHandler::HandleRequest(
|
||||||
|
const WaitGroup::Ptr&,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
|
@ -14,6 +14,7 @@ public:
|
|||||||
DECLARE_PTR_TYPEDEFS(StatusHandler);
|
DECLARE_PTR_TYPEDEFS(StatusHandler);
|
||||||
|
|
||||||
bool HandleRequest(
|
bool HandleRequest(
|
||||||
|
const WaitGroup::Ptr& waitGroup,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
|
@ -76,6 +76,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
bool TemplateQueryHandler::HandleRequest(
|
bool TemplateQueryHandler::HandleRequest(
|
||||||
|
const WaitGroup::Ptr&,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
|
@ -14,6 +14,7 @@ public:
|
|||||||
DECLARE_PTR_TYPEDEFS(TemplateQueryHandler);
|
DECLARE_PTR_TYPEDEFS(TemplateQueryHandler);
|
||||||
|
|
||||||
bool HandleRequest(
|
bool HandleRequest(
|
||||||
|
const WaitGroup::Ptr& waitGroup,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
|
@ -47,6 +47,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
bool TypeQueryHandler::HandleRequest(
|
bool TypeQueryHandler::HandleRequest(
|
||||||
|
const WaitGroup::Ptr&,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
|
@ -14,6 +14,7 @@ public:
|
|||||||
DECLARE_PTR_TYPEDEFS(TypeQueryHandler);
|
DECLARE_PTR_TYPEDEFS(TypeQueryHandler);
|
||||||
|
|
||||||
bool HandleRequest(
|
bool HandleRequest(
|
||||||
|
const WaitGroup::Ptr& waitGroup,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
|
@ -57,6 +57,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
bool VariableQueryHandler::HandleRequest(
|
bool VariableQueryHandler::HandleRequest(
|
||||||
|
const WaitGroup::Ptr&,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
|
@ -14,6 +14,7 @@ public:
|
|||||||
DECLARE_PTR_TYPEDEFS(VariableQueryHandler);
|
DECLARE_PTR_TYPEDEFS(VariableQueryHandler);
|
||||||
|
|
||||||
bool HandleRequest(
|
bool HandleRequest(
|
||||||
|
const WaitGroup::Ptr& waitGroup,
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
boost::beast::http::request<boost::beast::http::string_body>& request,
|
boost::beast::http::request<boost::beast::http::string_body>& request,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user