Skip to content

Commit fb879d7

Browse files
authored
Merge c7738f6 into 5688514
2 parents 5688514 + c7738f6 commit fb879d7

File tree

10 files changed

+258
-20
lines changed

10 files changed

+258
-20
lines changed

ydb/core/viewer/json_handlers_pdisk.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44
#include "json_handlers.h"
55

66
#include "json_pdisk_restart.h"
7+
#include "pdisk_info.h"
78

89

910
namespace NKikimr::NViewer {
1011

1112
void InitPDiskJsonHandlers(TJsonHandlers& jsonHandlers) {
1213
jsonHandlers.AddHandler("/pdisk/restart", new TJsonHandler<TJsonPDiskRestart>);
14+
jsonHandlers.AddHandler("/pdisk/info", new TJsonHandler<TPDiskInfo>);
1315
}
1416

1517
}

ydb/core/viewer/json_pdisk_restart.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ class TJsonPDiskRestart : public TViewerPipeClient<TJsonPDiskRestart> {
3232
using TBase = TViewerPipeClient<TThis>;
3333
IViewer* Viewer;
3434
NMon::TEvHttpInfo::TPtr Event;
35-
TJsonSettings JsonSettings;
36-
bool AllEnums = false;
3735
ui32 Timeout = 0;
3836
ui32 ActualRetries = 0;
3937
ui32 Retries = 0;
@@ -128,7 +126,7 @@ class TJsonPDiskRestart : public TViewerPipeClient<TJsonPDiskRestart> {
128126

129127
void HandleTimeout() {
130128
Send(Event->Sender, new NMon::TEvHttpInfoRes(
131-
Viewer->GetHTTPGATEWAYTIMEOUT(Event->Get(), "text/plain", "Timeout receiving response from NodeWarden"),
129+
Viewer->GetHTTPGATEWAYTIMEOUT(Event->Get(), "text/plain", "Timeout receiving response from BSC"),
132130
0, NMon::IEvHttpInfoRes::EContentType::Custom));
133131
}
134132

ydb/core/viewer/json_pipe_req.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <ydb/core/tx/scheme_cache/scheme_cache.h>
1111
#include <ydb/core/tx/schemeshard/schemeshard.h>
1212
#include <ydb/core/tx/tx_proxy/proxy.h>
13+
#include <ydb/core/sys_view/common/events.h>
1314
#include "viewer.h"
1415

1516
namespace NKikimr {
@@ -189,6 +190,18 @@ class TViewerPipeClient : public TActorBootstrapped<TDerived> {
189190
SendRequestToPipe(pipeClient, request.Release());
190191
}
191192

193+
void RequestBSControllerPDiskInfo(ui32 nodeId, ui32 pdiskId) {
194+
TActorId pipeClient = ConnectTabletPipe(GetBSControllerId());
195+
auto request = std::make_unique<NSysView::TEvSysView::TEvGetPDisksRequest>();
196+
request->Record.SetInclusiveFrom(true);
197+
request->Record.SetInclusiveTo(true);
198+
request->Record.MutableFrom()->SetNodeId(nodeId);
199+
request->Record.MutableFrom()->SetPDiskId(pdiskId);
200+
request->Record.MutableTo()->SetNodeId(nodeId);
201+
request->Record.MutableTo()->SetPDiskId(pdiskId);
202+
SendRequestToPipe(pipeClient, request.release());
203+
}
204+
192205
void RequestSchemeCacheNavigate(const TString& path) {
193206
THolder<NSchemeCache::TSchemeCacheNavigate> request = MakeHolder<NSchemeCache::TSchemeCacheNavigate>();
194207
NSchemeCache::TSchemeCacheNavigate::TEntry entry;

ydb/core/viewer/json_vdisk_evict.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ class TJsonVDiskEvict : public TViewerPipeClient<TJsonVDiskEvict> {
3232
using TBase = TViewerPipeClient<TThis>;
3333
IViewer* Viewer;
3434
NMon::TEvHttpInfo::TPtr Event;
35-
TJsonSettings JsonSettings;
3635
ui32 Timeout = 0;
3736
ui32 ActualRetries = 0;
3837
ui32 Retries = 0;
@@ -153,7 +152,7 @@ class TJsonVDiskEvict : public TViewerPipeClient<TJsonVDiskEvict> {
153152

154153
void HandleTimeout() {
155154
Send(Event->Sender, new NMon::TEvHttpInfoRes(
156-
Viewer->GetHTTPGATEWAYTIMEOUT(Event->Get(), "text/plain", "Timeout receiving response from NodeWarden"),
155+
Viewer->GetHTTPGATEWAYTIMEOUT(Event->Get(), "text/plain", "Timeout receiving response from BSC"),
157156
0, NMon::IEvHttpInfoRes::EContentType::Custom));
158157
}
159158

ydb/core/viewer/pdisk_info.h

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
#pragma once
2+
#include <ydb/library/actors/core/actor_bootstrapped.h>
3+
#include <ydb/library/actors/core/interconnect.h>
4+
#include <ydb/library/actors/core/mon.h>
5+
#include <ydb/library/services/services.pb.h>
6+
#include <ydb/core/viewer/json/json.h>
7+
#include <ydb/core/viewer/yaml/yaml.h>
8+
#include <ydb/core/util/wildcard.h>
9+
#include <library/cpp/json/json_writer.h>
10+
#include "viewer.h"
11+
#include "json_pipe_req.h"
12+
13+
namespace NKikimr {
14+
namespace NViewer {
15+
16+
using namespace NActors;
17+
18+
class TPDiskInfo : public TViewerPipeClient<TPDiskInfo> {
19+
enum EEv {
20+
EvRetryNodeRequest = EventSpaceBegin(NActors::TEvents::ES_PRIVATE),
21+
EvEnd
22+
};
23+
24+
static_assert(EvEnd < EventSpaceEnd(NActors::TEvents::ES_PRIVATE), "expect EvEnd < EventSpaceEnd(TEvents::ES_PRIVATE)");
25+
26+
struct TEvRetryNodeRequest : NActors::TEventLocal<TEvRetryNodeRequest, EvRetryNodeRequest> {
27+
TEvRetryNodeRequest()
28+
{}
29+
};
30+
31+
protected:
32+
using TThis = TPDiskInfo;
33+
using TBase = TViewerPipeClient<TThis>;
34+
IViewer* Viewer;
35+
NMon::TEvHttpInfo::TPtr Event;
36+
ui32 Timeout = 0;
37+
ui32 ActualRetries = 0;
38+
ui32 Retries = 0;
39+
TDuration RetryPeriod = TDuration::MilliSeconds(500);
40+
41+
std::unique_ptr<NSysView::TEvSysView::TEvGetPDisksResponse> BSCResponse;
42+
std::unique_ptr<NNodeWhiteboard::TEvWhiteboard::TEvPDiskStateResponse> WhiteboardResponse;
43+
44+
ui32 NodeId = 0;
45+
ui32 PDiskId = 0;
46+
47+
public:
48+
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
49+
return NKikimrServices::TActivity::VIEWER_HANDLER;
50+
}
51+
52+
TPDiskInfo(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
53+
: Viewer(viewer)
54+
, Event(ev)
55+
{}
56+
57+
void Bootstrap() {
58+
const auto& params(Event->Get()->Request.GetParams());
59+
NodeId = FromStringWithDefault<ui32>(params.Get("node_id"), 0);
60+
PDiskId = FromStringWithDefault<ui32>(params.Get("pdisk_id"), Max<ui32>());
61+
62+
if (PDiskId == Max<ui32>()) {
63+
TBase::Send(Event->Sender, new NMon::TEvHttpInfoRes(
64+
Viewer->GetHTTPBADREQUEST(Event->Get(), "text/plain", "field 'pdisk_id' is required"),
65+
0, NMon::IEvHttpInfoRes::EContentType::Custom));
66+
return PassAway();
67+
}
68+
if (Event->Get()->Request.GetMethod() != HTTP_METHOD_GET) {
69+
TBase::Send(Event->Sender, new NMon::TEvHttpInfoRes(
70+
Viewer->GetHTTPBADREQUEST(Event->Get(), "text/plain", "Only GET method is allowed"),
71+
0, NMon::IEvHttpInfoRes::EContentType::Custom));
72+
return PassAway();
73+
}
74+
75+
if (!NodeId) {
76+
NodeId = TlsActivationContext->ActorSystem()->NodeId;
77+
}
78+
TBase::InitConfig(params);
79+
80+
Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
81+
Retries = FromStringWithDefault<ui32>(params.Get("retries"), 3);
82+
RetryPeriod = TDuration::MilliSeconds(FromStringWithDefault<ui32>(params.Get("retry_period"), RetryPeriod.MilliSeconds()));
83+
84+
SendWhiteboardRequest();
85+
SendBSCRequest();
86+
87+
TBase::Become(&TThis::StateWork, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
88+
}
89+
90+
STATEFN(StateWork) {
91+
switch (ev->GetTypeRewrite()) {
92+
hFunc(NNodeWhiteboard::TEvWhiteboard::TEvPDiskStateResponse, Handle);
93+
hFunc(NSysView::TEvSysView::TEvGetPDisksResponse, Handle);
94+
cFunc(TEvRetryNodeRequest::EventType, HandleRetry);
95+
cFunc(TEvents::TEvUndelivered::EventType, Undelivered);
96+
cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
97+
}
98+
}
99+
100+
void SendWhiteboardRequest() {
101+
TActorId whiteboardServiceId = NNodeWhiteboard::MakeNodeWhiteboardServiceId(NodeId);
102+
auto request = std::make_unique<NNodeWhiteboard::TEvWhiteboard::TEvPDiskStateRequest>();
103+
TBase::SendRequest(whiteboardServiceId, request.release(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, NodeId);
104+
}
105+
106+
void SendBSCRequest() {
107+
RequestBSControllerPDiskInfo(NodeId, PDiskId);
108+
}
109+
110+
bool RetryRequest() {
111+
if (Retries) {
112+
if (++ActualRetries <= Retries) {
113+
TBase::Schedule(RetryPeriod, new TEvRetryNodeRequest());
114+
return true;
115+
}
116+
}
117+
return false;
118+
}
119+
120+
void Undelivered() {
121+
if (!RetryRequest()) {
122+
TBase::RequestDone();
123+
}
124+
}
125+
126+
void Handle(NSysView::TEvSysView::TEvGetPDisksResponse::TPtr& ev) {
127+
BSCResponse.reset(ev->Release().Release());
128+
TBase::RequestDone();
129+
}
130+
131+
void Handle(NNodeWhiteboard::TEvWhiteboard::TEvPDiskStateResponse::TPtr& ev) {
132+
WhiteboardResponse.reset(ev->Release().Release());
133+
TBase::RequestDone();
134+
}
135+
136+
void HandleRetry() {
137+
SendWhiteboardRequest();
138+
}
139+
140+
void HandleTimeout() {
141+
Send(Event->Sender, new NMon::TEvHttpInfoRes(
142+
Viewer->GetHTTPGATEWAYTIMEOUT(Event->Get(), "text/plain", "Timeout receiving response from NodeWarden"),
143+
0, NMon::IEvHttpInfoRes::EContentType::Custom));
144+
}
145+
146+
void PassAway() override {
147+
TBase::Send(TActivationContext::InterconnectProxy(NodeId), new TEvents::TEvUnsubscribe());
148+
TBase::PassAway();
149+
}
150+
151+
void ReplyAndPassAway() {
152+
NKikimrViewer::TPDiskInfo proto;
153+
TStringStream json;
154+
if (WhiteboardResponse != nullptr && WhiteboardResponse->Record.PDiskStateInfoSize() > 0) {
155+
proto.MutableWhiteboard()->CopyFrom(WhiteboardResponse->Record.GetPDiskStateInfo(0));
156+
}
157+
if (BSCResponse != nullptr && BSCResponse->Record.EntriesSize() > 0) {
158+
proto.MutableBSC()->CopyFrom(BSCResponse->Record.GetEntries(0).GetInfo());
159+
}
160+
TProtoToJson::ProtoToJson(json, proto, {
161+
.EnumAsNumbers = false,
162+
});
163+
TBase::Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON(Event->Get(), json.Str()), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
164+
PassAway();
165+
}
166+
};
167+
168+
template <>
169+
YAML::Node TJsonRequestSwagger<TPDiskInfo>::GetSwagger() {
170+
YAML::Node node = YAML::Load(R"___(
171+
get:
172+
tags:
173+
- pdisk
174+
summary: Gets PDisk info
175+
description: Gets PDisk information from Whiteboard and BSC
176+
parameters:
177+
- name: node_id
178+
in: query
179+
description: node identifier
180+
type: integer
181+
- name: pdisk_id
182+
in: query
183+
description: pdisk identifier
184+
required: true
185+
type: integer
186+
- name: timeout
187+
in: query
188+
description: timeout in ms
189+
required: false
190+
type: integer
191+
responses:
192+
200:
193+
description: OK
194+
content:
195+
application/json:
196+
schema: {}
197+
400:
198+
description: Bad Request
199+
403:
200+
description: Forbidden
201+
504:
202+
description: Gateway Timeout
203+
)___");
204+
205+
node["get"]["responses"]["200"]["content"]["application/json"]["schema"] = TProtoToYaml::ProtoToYamlSchema<NKikimrViewer::TPDiskInfo>();
206+
YAML::Node properties(node["get"]["responses"]["200"]["content"]["application/json"]["schema"]["properties"]["BSC"]["properties"]);
207+
TProtoToYaml::FillEnum(properties["StatusV2"], NProtoBuf::GetEnumDescriptor<NKikimrBlobStorage::EDriveStatus>());
208+
TProtoToYaml::FillEnum(properties["DecommitStatus"], NProtoBuf::GetEnumDescriptor<NKikimrBlobStorage::EDecommitStatus>());
209+
TProtoToYaml::FillEnum(properties["Type"], NProtoBuf::GetEnumDescriptor<NKikimrBlobStorage::EPDiskType>());
210+
return node;
211+
}
212+
213+
}
214+
}

ydb/core/viewer/protos/viewer.proto

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import "ydb/core/protos/tablet.proto";
88
import "ydb/core/protos/hive.proto";
99
import "ydb/core/protos/kqp.proto";
1010
import "ydb/public/api/protos/ydb_cms.proto";
11+
import "ydb/core/protos/sys_view.proto";
1112

1213
package NKikimrViewer;
1314
option java_package = "ru.yandex.kikimr.proto";
@@ -626,3 +627,8 @@ message TQueryAutocomplete {
626627
TResult Result = 2;
627628
repeated string Error = 3;
628629
}
630+
631+
message TPDiskInfo {
632+
NKikimrWhiteboard.TPDiskStateInfo Whiteboard = 1;
633+
NKikimrSysView.TPDiskInfo BSC = 2;
634+
}

ydb/core/viewer/wb_req.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ class TWhiteboardRequest : public TViewerPipeClient<TDerived> {
8888
}
8989

9090
void SendNodeRequestToWhiteboard(TNodeId nodeId) {
91-
TActorId whiteboardServiceId = MakeNodeWhiteboardServiceId(nodeId );
91+
TActorId whiteboardServiceId = MakeNodeWhiteboardServiceId(nodeId);
9292
THolder<TRequestEventType> request = CloneRequest();
9393
BLOG_TRACE("Sent WhiteboardRequest to " << nodeId << " Request: " << request->Record.ShortDebugString());
9494
TBase::SendRequest(whiteboardServiceId, request.Release(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId);

ydb/core/viewer/ya.make

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ SRCS(
5454
json_wb_req.h
5555
json_whoami.h
5656
log.h
57+
pdisk_info.h
5758
query_autocomplete_helper.h
5859
viewer_request.cpp
5960
viewer_request.h
@@ -492,6 +493,7 @@ PEERDIR(
492493
ydb/core/node_whiteboard
493494
ydb/core/protos
494495
ydb/core/scheme
496+
ydb/core/sys_view/common
495497
ydb/core/tx/schemeshard
496498
ydb/core/tx/tx_proxy
497499
ydb/core/util

ydb/core/viewer/yaml/yaml.cpp

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,22 @@
1010
#undef GetMessage
1111
#endif
1212

13+
void TProtoToYaml::FillEnum(YAML::Node property, const ::google::protobuf::EnumDescriptor* enumDescriptor) {
14+
auto enm = property["enum"];
15+
auto valueCount = enumDescriptor->value_count();
16+
TString defaultValue;
17+
for (int i = 0; i < valueCount; ++i) {
18+
auto enumValueDescriptor = enumDescriptor->value(i);
19+
enm.push_back(enumValueDescriptor->name());
20+
if (!defaultValue) {
21+
defaultValue = enumValueDescriptor->name();
22+
}
23+
}
24+
if (defaultValue) {
25+
property["default"] = defaultValue;
26+
}
27+
}
28+
1329
YAML::Node TProtoToYaml::ProtoToYamlSchema(const ::google::protobuf::Descriptor* descriptor, std::unordered_set<const ::google::protobuf::Descriptor*>& descriptors) {
1430
using namespace ::google::protobuf;
1531
if (descriptor == nullptr) {
@@ -90,20 +106,7 @@ YAML::Node TProtoToYaml::ProtoToYamlSchema(const ::google::protobuf::Descriptor*
90106
}
91107

92108
if (fieldDescriptor->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
93-
auto enm = property["enum"];
94-
auto enumDescriptor = fieldDescriptor->enum_type();
95-
auto valueCount = enumDescriptor->value_count();
96-
TString defaultValue;
97-
for (int i = 0; i < valueCount; ++i) {
98-
auto enumValueDescriptor = enumDescriptor->value(i);
99-
enm.push_back(enumValueDescriptor->name());
100-
if (!defaultValue) {
101-
defaultValue = enumValueDescriptor->name();
102-
}
103-
}
104-
if (defaultValue) {
105-
property["default"] = defaultValue;
106-
}
109+
FillEnum(property, fieldDescriptor->enum_type());
107110
}
108111
}
109112
}

ydb/core/viewer/yaml/yaml.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
class TProtoToYaml {
99
public:
1010
static YAML::Node ProtoToYamlSchema(const ::google::protobuf::Descriptor* descriptor);
11+
static void FillEnum(YAML::Node property, const ::google::protobuf::EnumDescriptor* enumDescriptor);
1112

1213
template <typename ProtoType>
1314
static YAML::Node ProtoToYamlSchema() {

0 commit comments

Comments
 (0)