summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ydb/core/viewer/json_local_rpc.h134
-rw-r--r--ydb/core/viewer/json_pipe_req.cpp65
-rw-r--r--ydb/core/viewer/json_pipe_req.h3
-rw-r--r--ydb/core/viewer/operation_cancel.h31
-rw-r--r--ydb/core/viewer/operation_forget.h31
-rw-r--r--ydb/core/viewer/operation_get.h22
-rw-r--r--ydb/core/viewer/operation_list.h38
-rw-r--r--ydb/core/viewer/scheme_directory.h23
-rw-r--r--ydb/core/viewer/viewer.cpp2
-rw-r--r--ydb/core/viewer/viewer_describe_consumer.h30
-rw-r--r--ydb/core/viewer/viewer_describe_topic.h32
11 files changed, 130 insertions, 281 deletions
diff --git a/ydb/core/viewer/json_local_rpc.h b/ydb/core/viewer/json_local_rpc.h
index 8a9a68d3cb0..9ea337fcefe 100644
--- a/ydb/core/viewer/json_local_rpc.h
+++ b/ydb/core/viewer/json_local_rpc.h
@@ -1,11 +1,8 @@
#pragma once
#include "json_pipe_req.h"
-#include "viewer.h"
-#include <library/cpp/json/json_writer.h>
#include <ydb/core/grpc_services/local_rpc/local_rpc.h>
-namespace NKikimr {
-namespace NViewer {
+namespace NKikimr::NViewer {
struct TEvLocalRpcPrivate {
enum EEv {
@@ -26,27 +23,15 @@ struct TEvLocalRpcPrivate {
};
};
-using namespace NActors;
-using NSchemeShard::TEvSchemeShard;
-
template <class TProtoRequest, class TProtoResponse, class TProtoResult, class TProtoService, class TRpcEv>
-class TJsonLocalRpc : public TActorBootstrapped<TJsonLocalRpc<TProtoRequest, TProtoResponse, TProtoResult, TProtoService, TRpcEv>> {
+class TJsonLocalRpc : public TViewerPipeClient {
using TThis = TJsonLocalRpc<TProtoRequest, TProtoResponse, TProtoResult, TProtoService, TRpcEv>;
- using TBase = TActorBootstrapped<TThis>;
-
- using TBase::Send;
- using TBase::PassAway;
- using TBase::Become;
+ using TBase = TViewerPipeClient;
protected:
- IViewer* Viewer;
- NMon::TEvHttpInfo::TPtr Event;
- TProtoRequest Request;
+ using TBase::ReplyAndPassAway;
+ std::vector<HTTP_METHOD> AllowedMethods = {};
TAutoPtr<TEvLocalRpcPrivate::TEvGrpcRequestResult<TProtoResult>> Result;
-
- TJsonSettings JsonSettings;
- ui32 Timeout = 0;
- TString Database;
NThreading::TFuture<TProtoResponse> RpcFuture;
public:
@@ -54,13 +39,11 @@ public:
return NKikimrServices::TActivity::VIEWER_HANDLER;
}
- TJsonLocalRpc(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
- : Viewer(viewer)
- , Event(ev)
+ TJsonLocalRpc(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
+ : TBase(viewer, ev, TProtoRequest::descriptor()->name())
{}
- TProtoRequest Params2Proto(const TCgiParameters& params) {
- TProtoRequest request;
+ void Params2Proto(const TCgiParameters& params, TProtoRequest& request) {
using google::protobuf::Descriptor;
using google::protobuf::Reflection;
using google::protobuf::FieldDescriptor;
@@ -110,44 +93,52 @@ public:
}
}
}
- return request;
}
- TProtoRequest Params2Proto() {
- TProtoRequest request;
- NProtobufJson::TJson2ProtoConfig json2ProtoConfig;
- auto postData = Event->Get()->Request.GetPostContent();
- if (!postData.empty()) {
- try {
- NProtobufJson::Json2Proto(postData, request, json2ProtoConfig);
- }
- catch (const yexception& e) {
- ReplyAndPassAway(Viewer->GetHTTPBADREQUEST(Event->Get(), "text/plain", e.what()));
+ bool ValidateProto(TProtoRequest& request) {
+ using google::protobuf::Descriptor;
+ using google::protobuf::Reflection;
+ using google::protobuf::FieldDescriptor;
+ const Descriptor& descriptor = *TProtoRequest::GetDescriptor();
+ const Reflection& reflection = *TProtoRequest::GetReflection();
+ for (int idx = 0; idx < descriptor.field_count(); ++idx) {
+ const FieldDescriptor* field = descriptor.field(idx);
+ const auto& options(field->options());
+ if (options.HasExtension(Ydb::required)) {
+ if (options.GetExtension(Ydb::required)) {
+ if (!reflection.HasField(request, field)) {
+ ReplyAndPassAway(GetHTTPBADREQUEST("text/plain", TStringBuilder() << "field '" << field->name() << "' is required"));
+ return false;
+ }
+ }
}
- } else {
- const auto& params(Event->Get()->Request.GetParams());
- return Params2Proto(params);
}
- return request;
+ return true;
}
- bool PostToRequest() {
+ bool Params2Proto(TProtoRequest& request) {
auto postData = Event->Get()->Request.GetPostContent();
if (!postData.empty()) {
try {
- NProtobufJson::Json2Proto(postData, Request, {});
- return true;
+ NProtobufJson::Json2Proto(postData, request);
}
catch (const yexception& e) {
- ReplyAndPassAway(Viewer->GetHTTPBADREQUEST(Event->Get(), "text/plain", e.what()));
+ ReplyAndPassAway(GetHTTPBADREQUEST("text/plain", e.what()));
return false;
}
+ } else {
+ const auto& params(Event->Get()->Request.GetParams());
+ Params2Proto(params, request);
+ }
+ if (!ValidateProto(request)) {
+ return false;
}
return true;
}
- void SendGrpcRequest() {
- RpcFuture = NRpcService::DoLocalRpc<TRpcEv>(std::move(Request), Database, Event->Get()->UserToken, TlsActivationContext->ActorSystem());
+ void SendGrpcRequest(TProtoRequest&& request) {
+ // TODO(xenoxeno): pass trace id
+ RpcFuture = NRpcService::DoLocalRpc<TRpcEv>(std::move(request), Database, Event->Get()->UserToken, TlsActivationContext->ActorSystem());
RpcFuture.Subscribe([actorId = TBase::SelfId(), actorSystem = TlsActivationContext->ActorSystem()]
(const NThreading::TFuture<TProtoResponse>& future) {
auto& response = future.GetValueSync();
@@ -173,14 +164,21 @@ public:
}
virtual void Bootstrap() {
- const auto& params(Event->Get()->Request.GetParams());
- JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), true);
- JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), true);
- Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
-
- SendGrpcRequest();
-
- Become(&TThis::StateRequested, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
+ if (!AllowedMethods.empty() && std::find(AllowedMethods.begin(), AllowedMethods.end(), Event->Get()->Request.GetMethod()) == AllowedMethods.end()) {
+ return ReplyAndPassAway(GetHTTPBADREQUEST("text/plain", "Method is not allowed"));
+ }
+ if (Database.empty()) {
+ return ReplyAndPassAway(GetHTTPBADREQUEST("text/plain", "field 'database' is required"));
+ }
+ if (TBase::NeedToRedirect()) {
+ return;
+ }
+ TProtoRequest request;
+ if (!Params2Proto(request)) {
+ return;
+ }
+ SendGrpcRequest(std::move(request));
+ Become(&TThis::StateRequested, Timeout, new TEvents::TEvWakeup());
}
void Handle(typename TEvLocalRpcPrivate::TEvGrpcRequestResult<TProtoResult>::TPtr& ev) {
@@ -197,38 +195,24 @@ public:
void ReplyAndPassAway() {
if (Result && Result->Status) {
- if (!Result->Status->IsSuccess()) {
+ if (Result->Status->IsSuccess()) {
+ return ReplyAndPassAway(GetHTTPOKJSON(Result->Message));
+ } else {
NJson::TJsonValue json;
TString message;
MakeJsonErrorReply(json, message, Result->Status.value());
TStringStream stream;
NJson::WriteJson(&stream, &json);
if (Result->Status->GetStatus() == NYdb::EStatus::UNAUTHORIZED) {
- return ReplyAndPassAway(Viewer->GetHTTPFORBIDDEN(Event->Get(), "application/json", stream.Str()));
+ return ReplyAndPassAway(GetHTTPFORBIDDEN("application/json", stream.Str()), message);
} else {
- return ReplyAndPassAway(Viewer->GetHTTPBADREQUEST(Event->Get(), "application/json", stream.Str()));
+ return ReplyAndPassAway(GetHTTPBADREQUEST("application/json", stream.Str()), message);
}
- } else {
- TStringStream json;
- TProtoToJson::ProtoToJson(json, Result->Message, JsonSettings);
- return ReplyAndPassAway(Viewer->GetHTTPOKJSON(Event->Get(), json.Str()));
}
} else {
- return ReplyAndPassAway(Viewer->GetHTTPINTERNALERROR(Event->Get()));
+ return ReplyAndPassAway(GetHTTPINTERNALERROR("text/plain", "no Result or Status"), "internal error");
}
}
-
-
- void HandleTimeout() {
- ReplyAndPassAway(Viewer->GetHTTPGATEWAYTIMEOUT(Event->Get()));
- }
-
- void ReplyAndPassAway(TString data) {
- Send(Event->Sender, new NMon::TEvHttpInfoRes(data, 0, NMon::IEvHttpInfoRes::EContentType::Custom));
- PassAway();
- }
};
-
-}
-}
+} // namespace NKikimr::NViewer
diff --git a/ydb/core/viewer/json_pipe_req.cpp b/ydb/core/viewer/json_pipe_req.cpp
index 9ce9b8e3df7..ecd896f8494 100644
--- a/ydb/core/viewer/json_pipe_req.cpp
+++ b/ydb/core/viewer/json_pipe_req.cpp
@@ -599,6 +599,9 @@ void TViewerPipeClient::InitConfig(const TCgiParameters& params) {
Database = params.Get("tenant");
}
Direct = FromStringWithDefault<bool>(params.Get("direct"), Direct);
+ JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), true);
+ JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), true);
+ Timeout = TDuration::MilliSeconds(FromStringWithDefault<ui32>(params.Get("timeout"), Timeout.MilliSeconds()));
}
void TViewerPipeClient::InitConfig(const TRequestSettings& settings) {
@@ -655,6 +658,12 @@ TString TViewerPipeClient::GetHTTPOKJSON(const NJson::TJsonValue& response, TIns
return GetHTTPOKJSON(NJson::WriteJson(response, false), lastModified);
}
+TString TViewerPipeClient::GetHTTPOKJSON(const google::protobuf::Message& response, TInstant lastModified) {
+ TStringStream json;
+ TProtoToJson::ProtoToJson(json, response, JsonSettings);
+ return GetHTTPOKJSON(json.Str(), lastModified);
+}
+
TString TViewerPipeClient::GetHTTPGATEWAYTIMEOUT(TString contentType, TString response) {
return Viewer->GetHTTPGATEWAYTIMEOUT(GetRequest(), std::move(contentType), std::move(response));
}
@@ -696,41 +705,47 @@ void TViewerPipeClient::Handle(TEvTabletPipe::TEvClientConnected::TPtr& ev) {
}
void TViewerPipeClient::HandleResolveResource(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr& ev) {
- ResourceNavigateResponse->Set(std::move(ev));
- if (ResourceNavigateResponse->IsOk()) {
- TSchemeCacheNavigate::TEntry& entry(ResourceNavigateResponse->Get()->Request->ResultSet.front());
- SharedDatabase = CanonizePath(entry.Path);
- if (SharedDatabase == AppData()->TenantName) {
- Direct = true;
- return Bootstrap(); // retry bootstrap without redirect this time
+ if (ResourceNavigateResponse) {
+ ResourceNavigateResponse->Set(std::move(ev));
+ if (ResourceNavigateResponse->IsOk()) {
+ TSchemeCacheNavigate::TEntry& entry(ResourceNavigateResponse->Get()->Request->ResultSet.front());
+ SharedDatabase = CanonizePath(entry.Path);
+ if (SharedDatabase == AppData()->TenantName) {
+ Direct = true;
+ return Bootstrap(); // retry bootstrap without redirect this time
+ }
+ DatabaseBoardInfoResponse = MakeRequestStateStorageEndpointsLookup(SharedDatabase);
+ } else {
+ ReplyAndPassAway(GetHTTPBADREQUEST("text/plain", "Failed to resolve database - shared database not found"));
}
- DatabaseBoardInfoResponse = MakeRequestStateStorageEndpointsLookup(SharedDatabase);
- } else {
- ReplyAndPassAway(GetHTTPBADREQUEST("text/plain", "Failed to resolve database - shared database not found"));
}
}
void TViewerPipeClient::HandleResolveDatabase(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr& ev) {
- DatabaseNavigateResponse->Set(std::move(ev));
- if (DatabaseNavigateResponse->IsOk()) {
- TSchemeCacheNavigate::TEntry& entry(DatabaseNavigateResponse->Get()->Request->ResultSet.front());
- if (entry.DomainInfo && entry.DomainInfo->ResourcesDomainKey && entry.DomainInfo->DomainKey != entry.DomainInfo->ResourcesDomainKey) {
- ResourceNavigateResponse = MakeRequestSchemeCacheNavigate(TPathId(entry.DomainInfo->ResourcesDomainKey));
- Become(&TViewerPipeClient::StateResolveResource);
- return;
+ if (DatabaseNavigateResponse) {
+ DatabaseNavigateResponse->Set(std::move(ev));
+ if (DatabaseNavigateResponse->IsOk()) {
+ TSchemeCacheNavigate::TEntry& entry(DatabaseNavigateResponse->Get()->Request->ResultSet.front());
+ if (entry.DomainInfo && entry.DomainInfo->ResourcesDomainKey && entry.DomainInfo->DomainKey != entry.DomainInfo->ResourcesDomainKey) {
+ ResourceNavigateResponse = MakeRequestSchemeCacheNavigate(TPathId(entry.DomainInfo->ResourcesDomainKey));
+ Become(&TViewerPipeClient::StateResolveResource);
+ return;
+ }
+ DatabaseBoardInfoResponse = MakeRequestStateStorageEndpointsLookup(CanonizePath(entry.Path));
+ } else {
+ ReplyAndPassAway(GetHTTPBADREQUEST("text/plain", "Failed to resolve database - not found"));
}
- DatabaseBoardInfoResponse = MakeRequestStateStorageEndpointsLookup(CanonizePath(entry.Path));
- } else {
- ReplyAndPassAway(GetHTTPBADREQUEST("text/plain", "Failed to resolve database - not found"));
}
}
void TViewerPipeClient::HandleResolve(TEvStateStorage::TEvBoardInfo::TPtr& ev) {
- DatabaseBoardInfoResponse->Set(std::move(ev));
- if (DatabaseBoardInfoResponse->IsOk()) {
- ReplyAndPassAway(MakeForward(GetNodesFromBoardReply(DatabaseBoardInfoResponse->GetRef())));
- } else {
- ReplyAndPassAway(GetHTTPBADREQUEST("text/plain", "Failed to resolve database - no nodes found"));
+ if (DatabaseBoardInfoResponse) {
+ DatabaseBoardInfoResponse->Set(std::move(ev));
+ if (DatabaseBoardInfoResponse->IsOk()) {
+ ReplyAndPassAway(MakeForward(GetNodesFromBoardReply(DatabaseBoardInfoResponse->GetRef())));
+ } else {
+ ReplyAndPassAway(GetHTTPBADREQUEST("text/plain", "Failed to resolve database - no nodes found"));
+ }
}
}
diff --git a/ydb/core/viewer/json_pipe_req.h b/ydb/core/viewer/json_pipe_req.h
index 3871cce45d4..e5f7665f74f 100644
--- a/ydb/core/viewer/json_pipe_req.h
+++ b/ydb/core/viewer/json_pipe_req.h
@@ -45,6 +45,8 @@ protected:
NWilson::TSpan Span;
IViewer* Viewer = nullptr;
NMon::TEvHttpInfo::TPtr Event;
+ TJsonSettings JsonSettings;
+ TDuration Timeout = TDuration::Seconds(10);
struct TPipeInfo {
TActorId PipeClient;
@@ -289,6 +291,7 @@ protected:
TString GetHTTPOK(TString contentType = {}, TString response = {}, TInstant lastModified = {});
TString GetHTTPOKJSON(TString response = {}, TInstant lastModified = {});
TString GetHTTPOKJSON(const NJson::TJsonValue& response, TInstant lastModified = {});
+ TString GetHTTPOKJSON(const google::protobuf::Message& response, TInstant lastModified = {});
TString GetHTTPGATEWAYTIMEOUT(TString contentType = {}, TString response = {});
TString GetHTTPBADREQUEST(TString contentType = {}, TString response = {});
TString GetHTTPINTERNALERROR(TString contentType = {}, TString response = {});
diff --git a/ydb/core/viewer/operation_cancel.h b/ydb/core/viewer/operation_cancel.h
index dc55fc145fd..2ed03faa9b7 100644
--- a/ydb/core/viewer/operation_cancel.h
+++ b/ydb/core/viewer/operation_cancel.h
@@ -18,35 +18,8 @@ public:
TOperationCancel(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
: TBase(viewer, ev)
- {}
-
- void Bootstrap() override {
- if (Event->Get()->Request.GetMethod() != HTTP_METHOD_POST) {
- return ReplyAndPassAway(Viewer->GetHTTPBADREQUEST(Event->Get(), "text/plain", "Only POST method is allowed"));
- }
-
- if (!PostToRequest()) {
- return;
- }
-
- const auto& params(Event->Get()->Request.GetParams());
- if (params.Has("database")) {
- Database = params.Get("database");
- }
-
- if (Database.empty()) {
- return ReplyAndPassAway(Viewer->GetHTTPBADREQUEST(Event->Get(), "text/plain", "field 'database' is required"));
- }
-
- if (params.Has("id")) {
- Request.set_id(params.Get("id"));
- }
-
- if (Request.id().empty()) {
- return ReplyAndPassAway(Viewer->GetHTTPBADREQUEST(Event->Get(), "text/plain", "field 'id' is required"));
- }
-
- TBase::Bootstrap();
+ {
+ AllowedMethods = {HTTP_METHOD_POST};
}
static YAML::Node GetSwagger() {
diff --git a/ydb/core/viewer/operation_forget.h b/ydb/core/viewer/operation_forget.h
index 2ba96175553..330b03c88af 100644
--- a/ydb/core/viewer/operation_forget.h
+++ b/ydb/core/viewer/operation_forget.h
@@ -18,35 +18,8 @@ public:
TOperationForget(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
: TBase(viewer, ev)
- {}
-
- void Bootstrap() override {
- if (Event->Get()->Request.GetMethod() != HTTP_METHOD_POST) {
- return ReplyAndPassAway(Viewer->GetHTTPBADREQUEST(Event->Get(), "text/plain", "Only POST method is allowed"));
- }
-
- if (!PostToRequest()) {
- return;
- }
-
- const auto& params(Event->Get()->Request.GetParams());
- if (params.Has("database")) {
- Database = params.Get("database");
- }
-
- if (Database.empty()) {
- return ReplyAndPassAway(Viewer->GetHTTPBADREQUEST(Event->Get(), "text/plain", "field 'database' is required"));
- }
-
- if (params.Has("id")) {
- Request.set_id(params.Get("id"));
- }
-
- if (Request.id().empty()) {
- return ReplyAndPassAway(Viewer->GetHTTPBADREQUEST(Event->Get(), "text/plain", "field 'id' is required"));
- }
-
- TBase::Bootstrap();
+ {
+ AllowedMethods = {HTTP_METHOD_POST};
}
static YAML::Node GetSwagger() {
diff --git a/ydb/core/viewer/operation_get.h b/ydb/core/viewer/operation_get.h
index 3b9ffeb4b48..af951b43443 100644
--- a/ydb/core/viewer/operation_get.h
+++ b/ydb/core/viewer/operation_get.h
@@ -18,26 +18,8 @@ public:
TOperationGet(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
: TBase(viewer, ev)
- {}
-
- void Bootstrap() override {
- if (Event->Get()->Request.GetMethod() != HTTP_METHOD_GET) {
- return ReplyAndPassAway(Viewer->GetHTTPBADREQUEST(Event->Get(), "text/plain", "Only GET method is allowed"));
- }
- const auto& params(Event->Get()->Request.GetParams());
- if (params.Has("database")) {
- Database = params.Get("database");
- } else {
- return ReplyAndPassAway(Viewer->GetHTTPBADREQUEST(Event->Get(), "text/plain", "field 'database' is required"));
- }
-
- if (params.Has("id")) {
- Request.set_id(params.Get("id"));
- } else {
- return ReplyAndPassAway(Viewer->GetHTTPBADREQUEST(Event->Get(), "text/plain", "field 'id' is required"));
- }
-
- TBase::Bootstrap();
+ {
+ AllowedMethods = {HTTP_METHOD_GET};
}
static YAML::Node GetSwagger() {
diff --git a/ydb/core/viewer/operation_list.h b/ydb/core/viewer/operation_list.h
index 585f1812c17..e72925d302d 100644
--- a/ydb/core/viewer/operation_list.h
+++ b/ydb/core/viewer/operation_list.h
@@ -18,34 +18,8 @@ public:
TOperationList(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
: TBase(viewer, ev)
- {}
-
- void Bootstrap() override {
- if (Event->Get()->Request.GetMethod() != HTTP_METHOD_GET) {
- return ReplyAndPassAway(Viewer->GetHTTPBADREQUEST(Event->Get(), "text/plain", "Only GET method is allowed"));
- }
- const auto& params(Event->Get()->Request.GetParams());
- if (params.Has("database")) {
- Database = params.Get("database");
- } else {
- return ReplyAndPassAway(Viewer->GetHTTPBADREQUEST(Event->Get(), "text/plain", "field 'database' is required"));
- }
-
- if (params.Has("kind")) {
- Request.set_kind(params.Get("kind"));
- } else {
- return ReplyAndPassAway(Viewer->GetHTTPBADREQUEST(Event->Get(), "text/plain", "field 'kind' is required"));
- }
-
- if (params.Has("page_size")) {
- Request.set_page_size(FromStringWithDefault<ui32>(params.Get("page_size"), 0));
- }
-
- if (params.Has("page_token")) {
- Request.set_page_token(params.Get("page_token"));
- }
-
- TBase::Bootstrap();
+ {
+ AllowedMethods = {HTTP_METHOD_GET};
}
static YAML::Node GetSwagger() {
@@ -63,7 +37,13 @@ public:
type: string
- name: kind
in: query
- description: kind
+ description: >
+ kind:
+ * `ss/backgrounds`
+ * `export`
+ * `import`
+ * `buildindex`
+ * `scriptexec`
required: true
type: string
- name: page_size
diff --git a/ydb/core/viewer/scheme_directory.h b/ydb/core/viewer/scheme_directory.h
index 8198b0a8e59..b94597be93d 100644
--- a/ydb/core/viewer/scheme_directory.h
+++ b/ydb/core/viewer/scheme_directory.h
@@ -38,29 +38,6 @@ public:
TSchemeDirectoryRequest(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
: TBase(viewer, ev)
{}
-
- void Bootstrap() override {
- if (!TBase::PostToRequest()) {
- return;
- }
-
- const auto& params(TBase::Event->Get()->Request.GetParams());
- if (params.Has("database")) {
- TBase::Database = params.Get("database");
- }
- if (TBase::Database.empty()) {
- return TBase::ReplyAndPassAway(TBase::Viewer->GetHTTPBADREQUEST(TBase::Event->Get(), "text/plain", "field 'database' is required"));
- }
-
- if (params.Has("path")) {
- TBase::Request.set_path(params.Get("path"));
- }
- if (TBase::Request.path().empty()) {
- return TBase::ReplyAndPassAway(TBase::Viewer->GetHTTPBADREQUEST(TBase::Event->Get(), "text/plain", "field 'path' is required"));
- }
-
- TBase::Bootstrap();
- }
};
class TJsonSchemeDirectoryHandler : public TJsonHandler<TSchemeDirectory> {
diff --git a/ydb/core/viewer/viewer.cpp b/ydb/core/viewer/viewer.cpp
index 664514d3487..51f382b2c43 100644
--- a/ydb/core/viewer/viewer.cpp
+++ b/ydb/core/viewer/viewer.cpp
@@ -598,7 +598,7 @@ void TViewer::FillCORS(TStringBuilder& stream, const TRequestState& request) {
<< "Access-Control-Allow-Headers: Content-Type,Authorization,Origin,Accept,X-Trace-Verbosity,X-Want-Trace,traceparent\r\n"
<< "Access-Control-Expose-Headers: traceresponse,X-Worker-Name\r\n"
<< "Access-Control-Allow-Methods: OPTIONS,GET,POST,PUT,DELETE\r\n"
- << "Allow: OPTIONS, GET, POST, DELETE\r\n";
+ << "Allow: OPTIONS,GET,POST,DELETE\r\n";
}
}
diff --git a/ydb/core/viewer/viewer_describe_consumer.h b/ydb/core/viewer/viewer_describe_consumer.h
index d7544aae110..9c6e5dcfbe5 100644
--- a/ydb/core/viewer/viewer_describe_consumer.h
+++ b/ydb/core/viewer/viewer_describe_consumer.h
@@ -18,37 +18,15 @@ public:
TJsonDescribeConsumer(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
: TBase(viewer, ev)
- {}
+ {
+ AllowedMethods = {HTTP_METHOD_GET};
+ }
void Bootstrap() override {
- if (Event->Get()->Request.GetMethod() != HTTP_METHOD_GET) {
- return ReplyAndPassAway(Viewer->GetHTTPBADREQUEST(Event->Get(), "text/plain", "Only GET method is allowed"));
- }
const auto& params(Event->Get()->Request.GetParams());
- if (params.Has("database")) {
- Database = params.Get("database");
- } else if (params.Has("database_path")) {
+ if (params.Has("database_path")) {
Database = params.Get("database_path");
- } else {
- return ReplyAndPassAway(Viewer->GetHTTPBADREQUEST(Event->Get(), "text/plain", "field 'database' is required"));
}
-
- if (params.Has("consumer")) {
- Request.set_consumer(params.Get("consumer"));
- } else {
- return ReplyAndPassAway(Viewer->GetHTTPBADREQUEST(Event->Get(), "text/plain", "field 'consumer' is required"));
- }
-
- if (params.Has("path")) {
- Request.set_path(params.Get("path"));
- } else {
- return ReplyAndPassAway(Viewer->GetHTTPBADREQUEST(Event->Get(), "text/plain", "field 'path' is required"));
- }
-
- if (params.Has("include_stats")) {
- Request.set_include_stats(FromStringWithDefault<bool>(params.Get("include_stats"), false));
- }
-
TBase::Bootstrap();
}
diff --git a/ydb/core/viewer/viewer_describe_topic.h b/ydb/core/viewer/viewer_describe_topic.h
index 5e94d20097b..007526f0f41 100644
--- a/ydb/core/viewer/viewer_describe_topic.h
+++ b/ydb/core/viewer/viewer_describe_topic.h
@@ -6,10 +6,10 @@
namespace NKikimr::NViewer {
using TDescribeTopicRpc = TJsonLocalRpc<Ydb::Topic::DescribeTopicRequest,
- Ydb::Topic::DescribeTopicResponse,
- Ydb::Topic::DescribeTopicResult,
- Ydb::Topic::V1::TopicService,
- NKikimr::NGRpcService::TEvDescribeTopicRequest>;
+ Ydb::Topic::DescribeTopicResponse,
+ Ydb::Topic::DescribeTopicResult,
+ Ydb::Topic::V1::TopicService,
+ NKikimr::NGRpcService::TEvDescribeTopicRequest>;
class TJsonDescribeTopic : public TDescribeTopicRpc {
public:
@@ -17,31 +17,15 @@ public:
TJsonDescribeTopic(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
: TBase(viewer, ev)
- {}
+ {
+ AllowedMethods = {HTTP_METHOD_GET};
+ }
void Bootstrap() override {
- if (Event->Get()->Request.GetMethod() != HTTP_METHOD_GET) {
- return ReplyAndPassAway(Viewer->GetHTTPBADREQUEST(Event->Get(), "text/plain", "Only GET method is allowed"));
- }
const auto& params(Event->Get()->Request.GetParams());
- if (params.Has("database")) {
- Database = params.Get("database");
- } else if (params.Has("database_path")) {
+ if (params.Has("database_path")) {
Database = params.Get("database_path");
- } else {
- return ReplyAndPassAway(Viewer->GetHTTPBADREQUEST(Event->Get(), "text/plain", "field 'database' is required"));
- }
-
- if (params.Has("path")) {
- Request.set_path(params.Get("path"));
- } else {
- return ReplyAndPassAway(Viewer->GetHTTPBADREQUEST(Event->Get(), "text/plain", "field 'path' is required"));
}
-
- if (params.Has("include_stats")) {
- Request.set_include_stats(FromStringWithDefault<bool>(params.Get("include_stats"), false));
- }
-
TBase::Bootstrap();
}