diff options
| -rw-r--r-- | ydb/core/viewer/json_local_rpc.h | 134 | ||||
| -rw-r--r-- | ydb/core/viewer/json_pipe_req.cpp | 65 | ||||
| -rw-r--r-- | ydb/core/viewer/json_pipe_req.h | 3 | ||||
| -rw-r--r-- | ydb/core/viewer/operation_cancel.h | 31 | ||||
| -rw-r--r-- | ydb/core/viewer/operation_forget.h | 31 | ||||
| -rw-r--r-- | ydb/core/viewer/operation_get.h | 22 | ||||
| -rw-r--r-- | ydb/core/viewer/operation_list.h | 38 | ||||
| -rw-r--r-- | ydb/core/viewer/scheme_directory.h | 23 | ||||
| -rw-r--r-- | ydb/core/viewer/viewer.cpp | 2 | ||||
| -rw-r--r-- | ydb/core/viewer/viewer_describe_consumer.h | 30 | ||||
| -rw-r--r-- | ydb/core/viewer/viewer_describe_topic.h | 32 |
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(); } |
