diff options
author | andrew-rykov <arykov@ydb.tech> | 2023-05-04 21:25:51 +0300 |
---|---|---|
committer | andrew-rykov <arykov@ydb.tech> | 2023-05-04 21:25:51 +0300 |
commit | 39dbe897485c57a12a6c8027ed787d70f9d31433 (patch) | |
tree | 5e712ad1b073e68abef87257b1ef7bb8c629c152 | |
parent | d8041116809f56885d742109346f7d530e7b0def (diff) | |
download | ydb-39dbe897485c57a12a6c8027ed787d70f9d31433.tar.gz |
get info from cache for describe handler
added cache from txproxy reply
schemeboard
-rw-r--r-- | ydb/core/viewer/json_describe.h | 172 | ||||
-rw-r--r-- | ydb/core/viewer/protos/viewer.proto | 21 |
2 files changed, 181 insertions, 12 deletions
diff --git a/ydb/core/viewer/json_describe.h b/ydb/core/viewer/json_describe.h index 26bfd3109b8..2521edab600 100644 --- a/ydb/core/viewer/json_describe.h +++ b/ydb/core/viewer/json_describe.h @@ -1,4 +1,5 @@ #pragma once +#include <ydb/core/tx/scheme_board/cache.h> #include <library/cpp/actors/core/actor_bootstrapped.h> #include <library/cpp/actors/core/mon.h> #include <ydb/core/base/tablet_pipe.h> @@ -13,15 +14,19 @@ namespace NViewer { using namespace NActors; using NSchemeShard::TEvSchemeShard; +using TNavigate = NSchemeCache::TSchemeCacheNavigate; class TJsonDescribe : public TViewerPipeClient<TJsonDescribe> { using TBase = TViewerPipeClient<TJsonDescribe>; IViewer* Viewer; NMon::TEvHttpInfo::TPtr Event; - TAutoPtr<TEvSchemeShard::TEvDescribeSchemeResult> DescribeResult; + TAutoPtr<TEvSchemeShard::TEvDescribeSchemeResult> SchemeShardResult; + TAutoPtr<TEvTxProxySchemeCache::TEvNavigateKeySetResult> CacheResult; + TAutoPtr<NKikimrViewer::TEvDescribeSchemeInfo> DescribeResult; TJsonSettings JsonSettings; ui32 Timeout = 0; bool ExpandSubElements = true; + int Requests = 0; public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { @@ -71,30 +76,175 @@ public: request->Record.SetUserToken(Event->Get()->UserToken); SendRequest(MakeTxProxyID(), request.Release()); } + ++Requests; + + if (params.Has("path")) { + TAutoPtr<NSchemeCache::TSchemeCacheNavigate> request(new NSchemeCache::TSchemeCacheNavigate()); + NSchemeCache::TSchemeCacheNavigate::TEntry entry; + entry.Operation = NSchemeCache::TSchemeCacheNavigate::OpList; + entry.SyncVersion = false; + entry.Path = SplitPath(params.Get("path")); + request->ResultSet.emplace_back(entry); + SendRequest(MakeSchemeCacheID(), new TEvTxProxySchemeCache::TEvNavigateKeySet(request)); + ++Requests; + } + Become(&TThis::StateRequestedDescribe, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup()); } STATEFN(StateRequestedDescribe) { switch (ev->GetTypeRewrite()) { hFunc(TEvSchemeShard::TEvDescribeSchemeResult, Handle); + hFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, Handle); hFunc(TEvTabletPipe::TEvClientConnected, TBase::Handle); cFunc(TEvents::TSystem::Wakeup, HandleTimeout); } } void Handle(TEvSchemeShard::TEvDescribeSchemeResult::TPtr& ev) { - DescribeResult = ev->Release(); - RequestDone(); + SchemeShardResult = ev->Release(); + if (SchemeShardResult->GetRecord().GetStatus() == NKikimrScheme::EStatus::StatusSuccess) { + ReplyAndPassAway(); + } else { + RequestDone("TEvDescribeSchemeResult"); + } + } + + void Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr &ev) { + CacheResult = ev->Release(); + RequestDone("TEvNavigateKeySetResult"); + } + + void RequestDone(const char* name) { + --Requests; + if (Requests == 0) { + ReplyAndPassAway(); + } + if (Requests < 0) { + BLOG_CRIT("Requests < 0 in RequestDone(" << name << ")"); + } + } + + void FillDescription(NKikimrSchemeOp::TDirEntry* descr, ui64 schemeShardId) { + descr->SetSchemeshardId(schemeShardId); + descr->SetPathId(InvalidLocalPathId); + descr->SetParentPathId(InvalidLocalPathId); + descr->SetCreateFinished(true); + descr->SetCreateTxId(0); + descr->SetCreateStep(0); + } + + NKikimrSchemeOp::EPathType ConvertType(TNavigate::EKind navigate) { + switch (navigate) { + case TNavigate::KindSubdomain: + return NKikimrSchemeOp::EPathTypeSubDomain; + case TNavigate::KindPath: + return NKikimrSchemeOp::EPathTypeDir; + case TNavigate::KindExtSubdomain: + return NKikimrSchemeOp::EPathTypeExtSubDomain; + case TNavigate::KindTable: + return NKikimrSchemeOp::EPathTypeTable; + case TNavigate::KindOlapStore: + return NKikimrSchemeOp::EPathTypeColumnStore; + case TNavigate::KindColumnTable: + return NKikimrSchemeOp::EPathTypeColumnTable; + case TNavigate::KindRtmr: + return NKikimrSchemeOp::EPathTypeRtmrVolume; + case TNavigate::KindKesus: + return NKikimrSchemeOp::EPathTypeKesus; + case TNavigate::KindSolomon: + return NKikimrSchemeOp::EPathTypeSolomonVolume; + case TNavigate::KindTopic: + return NKikimrSchemeOp::EPathTypePersQueueGroup; + case TNavigate::KindCdcStream: + return NKikimrSchemeOp::EPathTypeCdcStream; + case TNavigate::KindSequence: + return NKikimrSchemeOp::EPathTypeSequence; + case TNavigate::KindReplication: + return NKikimrSchemeOp::EPathTypeReplication; + case TNavigate::KindBlobDepot: + return NKikimrSchemeOp::EPathTypeBlobDepot; + case TNavigate::KindExternalTable: + return NKikimrSchemeOp::EPathTypeExternalTable; + case TNavigate::KindExternalDataSource: + return NKikimrSchemeOp::EPathTypeExternalDataSource; + case TNavigate::KindBlockStoreVolume: + return NKikimrSchemeOp::EPathTypeBlockStoreVolume; + case TNavigate::KindFileStore: + return NKikimrSchemeOp::EPathTypeFileStore; + default: + return NKikimrSchemeOp::EPathTypeDir; + } + } + + TAutoPtr<NKikimrViewer::TEvDescribeSchemeInfo> GetSchemeShardDescribeSchemeInfo() { + TAutoPtr<NKikimrViewer::TEvDescribeSchemeInfo> result(new NKikimrViewer::TEvDescribeSchemeInfo()); + auto& record = SchemeShardResult->GetRecord(); + const auto *descriptor = NKikimrScheme::EStatus_descriptor(); + result->SetStatus(descriptor->FindValueByNumber(record.GetStatus())->name()); + result->SetReason(record.GetReason()); + result->SetPath(record.GetPath()); + result->MutablePathDescription()->CopyFrom(record.GetPathDescription()); + result->SetPathOwner(record.GetPathOwner()); + result->SetPathId(record.GetPathId()); + result->SetLastExistedPrefixPath(record.GetLastExistedPrefixPath()); + result->SetLastExistedPrefixPathId(record.GetLastExistedPrefixPathId()); + result->MutableLastExistedPrefixDescription()->CopyFrom(record.GetLastExistedPrefixDescription()); + result->SetPathOwnerId(record.GetPathOwnerId()); + result->SetSource(NKikimrViewer::TEvDescribeSchemeInfo::SchemeShard); + + return result; + } + + TAutoPtr<NKikimrViewer::TEvDescribeSchemeInfo> GetCacheDescribeSchemeInfo() { + const auto& entry = CacheResult->Request.Get()->ResultSet.front(); + const auto& path = Event->Get()->Request.GetParams().Get("path"); + const auto& pathId = TPathId(); + const auto& schemeShardId = entry.DomainInfo->DomainKey.OwnerId; + + TAutoPtr<NKikimrViewer::TEvDescribeSchemeInfo> result(new NKikimrViewer::TEvDescribeSchemeInfo()); + result->SetPath(path); + result->SetPathOwner(schemeShardId); + result->SetPathId(pathId.LocalPathId); + result->SetPathOwnerId(pathId.OwnerId); + + auto* pathDescription = result->MutablePathDescription(); + auto* self = pathDescription->MutableSelf(); + + self->CopyFrom(entry.Self->Info); + FillDescription(self, schemeShardId); + + if (entry.ListNodeEntry) { + for (const auto& child : entry.ListNodeEntry->Children) { + auto descr = pathDescription->AddChildren(); + descr->SetName(child.Name); + descr->SetPathType(ConvertType(child.Kind)); + FillDescription(descr, schemeShardId); + } + }; + const auto *descriptor = NKikimrScheme::EStatus_descriptor(); + auto status = descriptor->FindValueByNumber(NKikimrScheme::StatusSuccess)->name(); + result->SetStatus(status); + result->SetSource(NKikimrViewer::TEvDescribeSchemeInfo::Cache); + return result; } void ReplyAndPassAway() { TStringStream json; TString headers = Viewer->GetHTTPOKJSON(Event->Get()); + if (SchemeShardResult != nullptr && SchemeShardResult->GetRecord().GetStatus() == NKikimrScheme::EStatus::StatusSuccess) { + DescribeResult = GetSchemeShardDescribeSchemeInfo(); + } else if (CacheResult != nullptr) { + NSchemeCache::TSchemeCacheNavigate *navigate = CacheResult->Request.Get(); + Y_VERIFY(navigate->ResultSet.size() == 1); + if (navigate->ErrorCount == 0) { + DescribeResult = GetCacheDescribeSchemeInfo(); + } + } if (DescribeResult != nullptr) { if (ExpandSubElements) { - NKikimrScheme::TEvDescribeSchemeResult& describe = *(DescribeResult->MutableRecord()); - if (describe.HasPathDescription()) { - auto& pathDescription = *describe.MutablePathDescription(); + if (DescribeResult->HasPathDescription()) { + auto& pathDescription = *DescribeResult->MutablePathDescription(); if (pathDescription.HasTable()) { auto& table = *pathDescription.MutableTable(); for (auto& tableIndex : table.GetTableIndexes()) { @@ -110,14 +260,12 @@ public: } } } - TProtoToJson::ProtoToJson(json, DescribeResult->GetRecord(), JsonSettings); - switch (DescribeResult->GetRecord().GetStatus()) { - case NKikimrScheme::StatusAccessDenied: + const auto *descriptor = NKikimrScheme::EStatus_descriptor(); + auto accessDeniedStatus = descriptor->FindValueByNumber(NKikimrScheme::StatusAccessDenied)->name(); + if (DescribeResult->GetStatus() == accessDeniedStatus) { headers = HTTPFORBIDDENJSON; - break; - default: - break; } + TProtoToJson::ProtoToJson(json, *DescribeResult, JsonSettings); } else { json << "null"; } diff --git a/ydb/core/viewer/protos/viewer.proto b/ydb/core/viewer/protos/viewer.proto index f5ee46e4978..baf3bff3839 100644 --- a/ydb/core/viewer/protos/viewer.proto +++ b/ydb/core/viewer/protos/viewer.proto @@ -506,3 +506,24 @@ message TEvViewerResponse { NKikimrWhiteboard.TEvTabletStateResponse TabletResponse = 11; } } + +message TEvDescribeSchemeInfo { + enum ESource { + None = 0; + SchemeShard = 1; + Cache = 2; + } + + optional string Status = 1; + optional string Reason = 2; + optional string Path = 3; + optional NKikimrSchemeOp.TPathDescription PathDescription = 4; + optional fixed64 PathOwner = 5; + optional fixed64 PathId = 6; + + optional string LastExistedPrefixPath = 7; + optional fixed64 LastExistedPrefixPathId = 8; + optional NKikimrSchemeOp.TPathDescription LastExistedPrefixDescription = 9; + optional fixed64 PathOwnerId = 10; + optional ESource Source = 11; +} |