This is an automated email from the ASF dual-hosted git repository.
alexey pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kudu.git
The following commit(s) were added to refs/heads/master by this push:
new d2b70fef7 KUDU-3543: Add JSON Content-Type Header
d2b70fef7 is described below
commit d2b70fef79d963099c8def7632521d3f31da81ff
Author: Marton Greber <[email protected]>
AuthorDate: Mon Aug 12 14:46:11 2024 +0000
KUDU-3543: Add JSON Content-Type Header
This patch introduces path handlers for pages that require the
Content-Type header application/json and integrates them accordingly.
Additionally, the test data has been updated to ensure proper coverage.
Change-Id: I37b442cb3e8be68f7b243e66ed5ebe369df07829
Reviewed-on: http://gerrit.cloudera.org:8080/21661
Tested-by: Alexey Serbin <[email protected]>
Reviewed-by: Alexey Serbin <[email protected]>
---
src/kudu/master/master_path_handlers.cc | 4 ++--
src/kudu/server/default_path_handlers.cc | 6 ++----
src/kudu/server/rpcz-path-handler.cc | 4 ++--
src/kudu/server/tracing_path_handlers.cc | 4 ++--
src/kudu/server/webserver.cc | 15 +++++++++++++++
src/kudu/server/webserver.h | 7 +++++++
src/kudu/util/jwt-util-test.cc | 8 ++++----
src/kudu/util/mini_oidc.cc | 9 +++------
src/kudu/util/test_util.cc | 29 +++++++++++++++--------------
src/kudu/util/web_callback_registry.h | 11 ++++++++++-
10 files changed, 62 insertions(+), 35 deletions(-)
diff --git a/src/kudu/master/master_path_handlers.cc
b/src/kudu/master/master_path_handlers.cc
index f1c36fdfe..fb6efc484 100644
--- a/src/kudu/master/master_path_handlers.cc
+++ b/src/kudu/master/master_path_handlers.cc
@@ -915,12 +915,12 @@ Status MasterPathHandlers::Register(Webserver* server) {
[this](const Webserver::WebRequest& req,
Webserver::PrerenderedWebResponse* resp) {
this->HandleIpkiCaCert(DataFormat::DER, req, resp);
});
- server->RegisterPrerenderedPathHandler(
+ server->RegisterJsonPathHandler(
"/dump-entities", "Dump Entities",
[this](const Webserver::WebRequest& req,
Webserver::PrerenderedWebResponse* resp) {
this->HandleDumpEntities(req, resp);
},
- StyleMode::UNSTYLED, false);
+ false /*is_on_nav_bar*/);
return Status::OK();
}
diff --git a/src/kudu/server/default_path_handlers.cc
b/src/kudu/server/default_path_handlers.cc
index 7457710ac..e125d9658 100644
--- a/src/kudu/server/default_path_handlers.cc
+++ b/src/kudu/server/default_path_handlers.cc
@@ -533,13 +533,11 @@ void RegisterMetricsJsonHandler(Webserver* webserver,
const MetricRegistry* cons
};
bool not_on_nav_bar = false;
bool is_on_nav_bar = true;
- webserver->RegisterPrerenderedPathHandler("/metrics", "JSON Metrics",
callback,
- StyleMode::UNSTYLED,
is_on_nav_bar);
+ webserver->RegisterJsonPathHandler("/metrics", "JSON Metrics", callback,
is_on_nav_bar);
// The old name -- this is preserved for compatibility with older releases of
// monitoring software which expects the old name.
- webserver->RegisterPrerenderedPathHandler("/jsonmetricz", "Metrics",
callback,
- StyleMode::UNSTYLED,
not_on_nav_bar);
+ webserver->RegisterJsonPathHandler("/jsonmetricz", "Metrics", callback,
not_on_nav_bar);
}
void RegisterMetricsPrometheusHandler(Webserver* webserver, const
MetricRegistry* const metrics) {
diff --git a/src/kudu/server/rpcz-path-handler.cc
b/src/kudu/server/rpcz-path-handler.cc
index 159639f9d..53b05daa1 100644
--- a/src/kudu/server/rpcz-path-handler.cc
+++ b/src/kudu/server/rpcz-path-handler.cc
@@ -77,12 +77,12 @@ void RpczPathHandler(const shared_ptr<Messenger>& messenger,
} // anonymous namespace
void AddRpczPathHandlers(const shared_ptr<Messenger>& messenger, Webserver*
webserver) {
- webserver->RegisterPrerenderedPathHandler(
+ webserver->RegisterJsonPathHandler(
"/rpcz", "RPCs",
[messenger](const Webserver::WebRequest& req,
Webserver::PrerenderedWebResponse* resp) {
RpczPathHandler(messenger, req, resp);
},
- StyleMode::UNSTYLED, true /*is_on_nav_bar*/);
+ true /*is_on_nav_bar*/);
}
} // namespace kudu
diff --git a/src/kudu/server/tracing_path_handlers.cc
b/src/kudu/server/tracing_path_handlers.cc
index 086424936..fe51f05dd 100644
--- a/src/kudu/server/tracing_path_handlers.cc
+++ b/src/kudu/server/tracing_path_handlers.cc
@@ -273,11 +273,11 @@ void TracingPathHandlers::RegisterHandlers(Webserver*
server) {
typedef pair<const string, Handler> HandlerPair;
for (const HandlerPair& e : handlers) {
- server->RegisterPrerenderedPathHandler(
+ server->RegisterJsonPathHandler(
e.first, "", [e](const Webserver::WebRequest& req,
Webserver::PrerenderedWebResponse* resp) {
HandleRequest(e.second, req, resp);
- }, StyleMode::UNSTYLED, false /* is_on_nav_bar */);
+ }, false /* is_on_nav_bar */);
}
}
diff --git a/src/kudu/server/webserver.cc b/src/kudu/server/webserver.cc
index 0a52227d3..a734259cb 100644
--- a/src/kudu/server/webserver.cc
+++ b/src/kudu/server/webserver.cc
@@ -754,6 +754,9 @@ void Webserver::SendResponse(struct sq_connection*
connection,
case StyleMode::BINARY:
content_type = "application/octet-stream";
break;
+ case StyleMode::JSON:
+ content_type = "application/json";
+ break;
default:
LOG(DFATAL) << "unexpected style mode: " << static_cast<uint32_t>(mode);
break;
@@ -870,6 +873,18 @@ void Webserver::RegisterBinaryDataPathHandler(
callback));
}
+void Webserver::RegisterJsonPathHandler(
+ const string& path,
+ const string& alias,
+ const PrerenderedPathHandlerCallback& callback,
+ bool is_on_nav_bar) {
+ std::lock_guard l(lock_);
+ InsertOrDie(&path_handlers_, path, new PathHandler(StyleMode::JSON,
+ is_on_nav_bar,
+ alias,
+ callback));
+}
+
bool Webserver::MustacheTemplateAvailable(const string& path) const {
if (!static_pages_available()) {
return false;
diff --git a/src/kudu/server/webserver.h b/src/kudu/server/webserver.h
index a1be885f0..3de8a8784 100644
--- a/src/kudu/server/webserver.h
+++ b/src/kudu/server/webserver.h
@@ -86,6 +86,13 @@ class Webserver : public WebCallbackRegistry {
const std::string& alias,
const PrerenderedPathHandlerCallback& callback) override;
+ // Register route 'path' for application/json responses.
+ void RegisterJsonPathHandler(
+ const std::string& path,
+ const std::string& alias,
+ const PrerenderedPathHandlerCallback& callback,
+ bool is_on_nav_bar) override;
+
// Change the footer HTML to be displayed at the bottom of all styled web
pages.
void set_footer_html(const std::string& html);
diff --git a/src/kudu/util/jwt-util-test.cc b/src/kudu/util/jwt-util-test.cc
index 0b2d380ec..a6e1cf341 100644
--- a/src/kudu/util/jwt-util-test.cc
+++ b/src/kudu/util/jwt-util-test.cc
@@ -850,8 +850,8 @@ class JWKSMockServer {
opts.port = 0;
opts.bind_interface = "127.0.0.1";
webserver_.reset(new Webserver(opts));
- webserver_->RegisterPrerenderedPathHandler("/jwks", "JWKS",
SimpleJWKSHandler,
- StyleMode::UNSTYLED,
/*is_on_nav_bar*/false);
+ webserver_->RegisterJsonPathHandler("/jwks", "JWKS", SimpleJWKSHandler,
+ /*is_on_nav_bar*/false);
RETURN_NOT_OK(webserver_->Start());
vector<Sockaddr> addrs;
RETURN_NOT_OK(webserver_->GetBoundAddresses(&addrs));
@@ -870,13 +870,13 @@ class JWKSMockServer {
for (const auto& ar : account_id_to_resp) {
const auto& account_id = ar.first;
const auto& jwks = ar.second;
- webserver_->RegisterPrerenderedPathHandler(Substitute("/jwks/$0",
account_id), account_id,
+ webserver_->RegisterJsonPathHandler(Substitute("/jwks/$0", account_id),
account_id,
[account_id, jwks] (const Webserver::WebRequest& /*req*/,
Webserver::PrerenderedWebResponse* resp) {
resp->output << jwks;
resp->status_code = HttpStatusCode::Ok;
},
- StyleMode::UNSTYLED, /*is_on_nav_bar*/false);
+ /*is_on_nav_bar*/false);
}
RETURN_NOT_OK(webserver_->Start());
vector<Sockaddr> addrs;
diff --git a/src/kudu/util/mini_oidc.cc b/src/kudu/util/mini_oidc.cc
index fda284588..3d53a1bb6 100644
--- a/src/kudu/util/mini_oidc.cc
+++ b/src/kudu/util/mini_oidc.cc
@@ -111,7 +111,7 @@ Status MiniOidc::Start() {
// For clients with oidc discovery
for (const auto& [account_id, valid] : options_.account_ids) {
- jwks_server_->RegisterPrerenderedPathHandler(
+ jwks_server_->RegisterJsonPathHandler(
Substitute("/jwks/$0", account_id),
account_id,
[account_id = account_id, valid = valid](const Webserver::WebRequest&
/*req*/,
@@ -126,12 +126,11 @@ Status MiniOidc::Start() {
kRsaInvalidPubKeyJwkN, kRsaPubKeyJwkE),
resp->status_code = HttpStatusCode::Ok;
},
- StyleMode::UNSTYLED,
/*is_on_nav_bar*/ false);
}
// for clients without oidc discovery
- jwks_server_->RegisterPrerenderedPathHandler(
+ jwks_server_->RegisterJsonPathHandler(
"/jwks.json",
"jwks",
[&](const Webserver::WebRequest& /*req*/,
Webserver::PrerenderedWebResponse* resp) {
@@ -146,7 +145,6 @@ Status MiniOidc::Start() {
kRsaPubKeyJwkE),
resp->status_code = HttpStatusCode::Ok;
},
- StyleMode::UNSTYLED,
/*is_on_nav_bar*/ false);
LOG(INFO) << "Starting JWKS server";
@@ -174,7 +172,7 @@ Status MiniOidc::Start() {
oidc_opts.port = 0;
oidc_opts.bind_interface = "localhost";
oidc_server_.reset(new Webserver(oidc_opts));
- oidc_server_->RegisterPrerenderedPathHandler(
+ oidc_server_->RegisterJsonPathHandler(
"/.well-known/openid-configuration",
"openid-configuration",
// Pass the 'accountId' query arguments to return a response that
@@ -183,7 +181,6 @@ Status MiniOidc::Start() {
Webserver::PrerenderedWebResponse* resp) {
OidcDiscoveryHandler(req, resp, discovery_jwks_url);
},
- StyleMode::UNSTYLED,
/*is_on_nav_bar*/ false);
LOG(INFO) << "Starting OIDC Discovery server";
diff --git a/src/kudu/util/test_util.cc b/src/kudu/util/test_util.cc
index 9129a5ce8..4afc40fc7 100644
--- a/src/kudu/util/test_util.cc
+++ b/src/kudu/util/test_util.cc
@@ -100,6 +100,7 @@ static const uint64_t kTestBeganAtMicros =
Env::Default()->NowMicros();
static const char* const kContentTypeTextPlain = "text/plain";
static const char* const kContentTypeTextHtml = "text/html";
static const char* const kContentTypeApplicationOctet =
"application/octet-stream";
+static const char* const kContentTypeApplicationJson = "application/json";
// Global which production code can check to see if it is running
// in a GTest environment (assuming the test binary links in this module,
@@ -667,10 +668,10 @@ const unordered_map<string, string>&
GetCommonWebserverEndpoints() {
{"stacks", kContentTypeTextPlain},
{"version", kContentTypeTextPlain},
{"healthz", kContentTypeTextPlain},
- {"metrics", kContentTypeTextPlain},
- {"jsonmetricz", kContentTypeTextPlain},
+ {"metrics", kContentTypeApplicationJson},
+ {"jsonmetricz", kContentTypeApplicationJson},
{"metrics_prometheus", kContentTypeTextPlain},
- {"rpcz", kContentTypeTextPlain},
+ {"rpcz", kContentTypeApplicationJson},
{"startup", kContentTypeTextHtml},
{"pprof/cmdline", kContentTypeTextPlain},
{"pprof/heap", kContentTypeTextPlain},
@@ -678,16 +679,16 @@ const unordered_map<string, string>&
GetCommonWebserverEndpoints() {
{"pprof/profile", kContentTypeTextPlain},
{"pprof/symbol", kContentTypeTextPlain},
{"pprof/contention", kContentTypeTextPlain},
- {"tracing/json/begin_monitoring", kContentTypeTextPlain},
- {"tracing/json/end_monitoring", kContentTypeTextPlain},
- {"tracing/json/capture_monitoring", kContentTypeTextPlain},
- {"tracing/json/get_monitoring_status", kContentTypeTextPlain},
- {"tracing/json/categories", kContentTypeTextPlain},
- {"tracing/json/begin_recording", kContentTypeTextPlain},
- {"tracing/json/get_buffer_percent_full", kContentTypeTextPlain},
- {"tracing/json/end_recording", kContentTypeTextPlain},
- {"tracing/json/end_recording_compressed", kContentTypeTextPlain},
- {"tracing/json/simple_dump", kContentTypeTextPlain}};
+ {"tracing/json/begin_monitoring", kContentTypeApplicationJson},
+ {"tracing/json/end_monitoring", kContentTypeApplicationJson},
+ {"tracing/json/capture_monitoring", kContentTypeApplicationJson},
+ {"tracing/json/get_monitoring_status", kContentTypeApplicationJson},
+ {"tracing/json/categories", kContentTypeApplicationJson},
+ {"tracing/json/begin_recording", kContentTypeApplicationJson},
+ {"tracing/json/get_buffer_percent_full", kContentTypeApplicationJson},
+ {"tracing/json/end_recording", kContentTypeApplicationJson},
+ {"tracing/json/end_recording_compressed", kContentTypeApplicationJson},
+ {"tracing/json/simple_dump", kContentTypeApplicationJson}};
return common_endpoints;
}
@@ -716,7 +717,7 @@ const unordered_map<string, string>&
GetMasterWebserverEndpoints(const string& t
{"ipki-ca-cert", kContentTypeTextPlain},
{"ipki-ca-cert-pem", kContentTypeTextPlain},
{"ipki-ca-cert-der", kContentTypeApplicationOctet},
- {"dump-entities", kContentTypeTextPlain}};
+ {"dump-entities", kContentTypeApplicationJson}};
return master_endpoints;
}
diff --git a/src/kudu/util/web_callback_registry.h
b/src/kudu/util/web_callback_registry.h
index d0e39db44..2c405de98 100644
--- a/src/kudu/util/web_callback_registry.h
+++ b/src/kudu/util/web_callback_registry.h
@@ -46,7 +46,9 @@ enum class StyleMode {
// In this mode, the response is sent without any styling elements.
UNSTYLED,
// In rare cases when a binary data is sent as a response.
- BINARY
+ BINARY,
+ // This mode is used when the server response is in JSON format.
+ JSON
};
// Interface for registering webserver callbacks.
@@ -146,6 +148,13 @@ class WebCallbackRegistry {
const std::string& alias,
const PrerenderedPathHandlerCallback& callback) = 0;
+ // Register a callback for a URL path that returns JSON.
+ virtual void RegisterJsonPathHandler(
+ const std::string& path,
+ const std::string& alias,
+ const PrerenderedPathHandlerCallback& callback,
+ bool is_on_nav_bar) = 0;
+
// Returns true if 'req' was proxied via Knox, false otherwise.
static bool IsProxiedViaKnox(const WebRequest& req);
};