Skip to content

Commit 8bc6d81

Browse files
authored
Added describe_replication method for embedded UI (#16059)
1 parent 70be00c commit 8bc6d81

File tree

6 files changed

+202
-1
lines changed

6 files changed

+202
-1
lines changed

ydb/core/grpc_services/rpc_replication.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,4 +246,11 @@ void DoDescribeReplication(std::unique_ptr<IRequestOpCtx> p, const IFacilityProv
246246
f.RegisterActor(new TDescribeReplicationRPC(p.release()));
247247
}
248248

249+
using TEvDescribeReplicationRequest = TGrpcRequestOperationCall<Ydb::Replication::DescribeReplicationRequest, Ydb::Replication::DescribeReplicationResponse>;
250+
251+
template<>
252+
IActor* TEvDescribeReplicationRequest::CreateRpcActor(NKikimr::NGRpcService::IRequestOpCtx* msg) {
253+
return new TDescribeReplicationRPC(msg);
254+
}
255+
249256
}

ydb/core/viewer/json_handlers_viewer.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "viewer_counters.h"
1111
#include "viewer_describe_consumer.h"
1212
#include "viewer_describe.h"
13+
#include "viewer_describe_replication.h"
1314
#include "viewer_describe_topic.h"
1415
#include "viewer_feature_flags.h"
1516
#include "viewer_topic_data.h"
@@ -156,6 +157,10 @@ void InitViewerDescribeJsonHandler(TJsonHandlers& jsonHandlers) {
156157
jsonHandlers.AddHandler("/viewer/describe", new TJsonHandler<TJsonDescribe>(TJsonDescribe::GetSwagger()));
157158
}
158159

160+
void InitViewerDescribeReplicationJsonHandler(TJsonHandlers& jsonHandlers) {
161+
jsonHandlers.AddHandler("/viewer/describe_replication", new TJsonHandler<TJsonDescribeReplication>(TJsonDescribeReplication::GetSwagger()));
162+
}
163+
159164
void InitViewerDescribeTopicJsonHandler(TJsonHandlers& jsonHandlers) {
160165
jsonHandlers.AddHandler("/viewer/describe_topic", new TJsonHandler<TJsonDescribeTopic>(TJsonDescribeTopic::GetSwagger()));
161166
}
@@ -299,6 +304,7 @@ void InitViewerJsonHandlers(TJsonHandlers& jsonHandlers) {
299304
InitViewerPDiskInfoJsonHandler(jsonHandlers);
300305
InitViewerTabletInfoJsonHandler(jsonHandlers);
301306
InitViewerDescribeJsonHandler(jsonHandlers);
307+
InitViewerDescribeReplicationJsonHandler(jsonHandlers);
302308
InitViewerDescribeTopicJsonHandler(jsonHandlers);
303309
InitViewerDescribeConsumerJsonHandler(jsonHandlers);
304310
InitViewerHotkeysJsonHandler(jsonHandlers);

ydb/core/viewer/tests/canondata/result.json

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,82 @@
654654
"Truncated": true
655655
}
656656
},
657+
658+
"test.test_transfer_describe": {
659+
"connection_params": {
660+
"connection_string": "text",
661+
"database": "/Root/dedicated_db",
662+
"endpoint": "text",
663+
"oauth": {}
664+
},
665+
"error": {
666+
"issues": [
667+
{
668+
"message": "Discovery error: /Root/dedicated_db/TopicNotExists: SCHEME_ERROR ({ <main>: Error: Path not found })",
669+
"severity": 1
670+
}
671+
]
672+
},
673+
"row_consistency": {},
674+
"self": {
675+
"created_at": {
676+
"plan_step": "not-zero-number-text",
677+
"tx_id": "not-zero-number-text"
678+
},
679+
"effective_permissions": [
680+
{
681+
"permission_names": [
682+
"ydb.database.connect"
683+
],
684+
"subject": "USERS"
685+
},
686+
{
687+
"permission_names": [
688+
"ydb.generic.list"
689+
],
690+
"subject": "METADATA-READERS"
691+
},
692+
{
693+
"permission_names": [
694+
"ydb.granular.select_row"
695+
],
696+
"subject": "DATA-READERS"
697+
},
698+
{
699+
"permission_names": [
700+
"ydb.tables.modify"
701+
],
702+
"subject": "DATA-WRITERS"
703+
},
704+
{
705+
"permission_names": [
706+
"ydb.granular.create_directory",
707+
"ydb.granular.write_attributes",
708+
"ydb.granular.create_table",
709+
"ydb.granular.remove_schema",
710+
"ydb.granular.create_queue",
711+
"ydb.granular.alter_schema"
712+
],
713+
"subject": "DDL-ADMINS"
714+
},
715+
{
716+
"permission_names": [
717+
"ydb.access.grant"
718+
],
719+
"subject": "ACCESS-ADMINS"
720+
},
721+
{
722+
"permission_names": [
723+
"ydb.generic.manage"
724+
],
725+
"subject": "DATABASE-ADMINS"
726+
}
727+
],
728+
"name": "TestTransfer",
729+
"owner": "root@builtin",
730+
"type": "TRANSFER"
731+
}
732+
},
657733
"test.test_viewer_acl": {
658734
"/Root": {
659735
"Common": {

ydb/core/viewer/tests/test.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import time
1111

1212

13-
cluster = KiKiMR(KikimrConfigGenerator(enable_alter_database_create_hive_first=True))
13+
cluster = KiKiMR(KikimrConfigGenerator(extra_feature_flags={'enable_alter_database_create_hive_first': True, 'enable_topic_transfer': True}))
1414
cluster.start()
1515
domain_name = '/' + cluster.domain_name
1616
dedicated_db = domain_name + "/dedicated_db"
@@ -402,6 +402,15 @@ def normalize_result_healthcheck(result):
402402
return result
403403

404404

405+
def normalize_result_replication(result):
406+
result = replace_values_by_key(result, ['connection_string',
407+
'endpoint',
408+
'plan_step',
409+
'tx_id'])
410+
delete_keys_recursively(result, ['issue_log'])
411+
return result
412+
413+
405414
def normalize_result(result):
406415
delete_keys_recursively(result, ['Version',
407416
'MemoryUsed',
@@ -421,6 +430,7 @@ def normalize_result(result):
421430
result = normalize_result_pdisks(result)
422431
result = normalize_result_vdisks(result)
423432
result = normalize_result_cluster(result)
433+
result = normalize_result_replication(result)
424434
return result
425435

426436

@@ -683,3 +693,30 @@ def strip_non_canonized(resp):
683693
'response_not_truncated': strip_non_canonized(response_last)
684694
}
685695
return result
696+
697+
698+
def test_transfer_describe():
699+
grpc_port = cluster.nodes[1].grpc_port
700+
endpoint = "grpc://localhost:{}/?database={}".format(grpc_port, dedicated_db)
701+
lambd = "($x) -> { RETURN <|Id:$x._offset|>; }"
702+
703+
call_viewer("/viewer/query", {
704+
'database': dedicated_db,
705+
'query': 'CREATE TABLE `TransferTargetTable` ( `Id` Uint64 NOT NULL PRIMARY KEY (Id)) WITH (STORE = COLUMN)',
706+
'schema': 'multi'
707+
})
708+
709+
call_viewer("/viewer/query", {
710+
'database': dedicated_db,
711+
'query': 'CREATE TRANSFER `TestTransfer` FROM `TopicNotExists` TO `Table` USING {} WITH (CONNECTION_STRING = "{}")'.format(lambd, endpoint),
712+
'schema': 'multi'
713+
})
714+
715+
result = get_viewer_normalized("/viewer/describe_replication", {
716+
'database': dedicated_db,
717+
'path': '{}/TestTransfer'.format(dedicated_db),
718+
'include_stats': 'true',
719+
'enums': 'true'
720+
})
721+
722+
return result
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#include "json_handlers.h"
2+
#include "json_local_rpc.h"
3+
4+
#include <ydb/core/grpc_services/rpc_calls.h>
5+
#include <ydb/core/grpc_services/service_replication.h>
6+
#include <ydb/services/replication/grpc_service.h>
7+
8+
namespace NKikimr::NGRpcService {
9+
using TEvDescribeReplicationRequest = TGrpcRequestOperationCall<Ydb::Replication::DescribeReplicationRequest, Ydb::Replication::DescribeReplicationResponse>;
10+
}
11+
12+
namespace NKikimr::NViewer {
13+
14+
using TDescribeReplicationRpc = TJsonLocalRpc<Ydb::Replication::DescribeReplicationRequest,
15+
Ydb::Replication::DescribeReplicationResponse,
16+
Ydb::Replication::DescribeReplicationResult,
17+
Ydb::Replication::V1::ReplicationService,
18+
NKikimr::NGRpcService::TEvDescribeReplicationRequest>;
19+
20+
class TJsonDescribeReplication : public TDescribeReplicationRpc {
21+
public:
22+
using TBase = TDescribeReplicationRpc;
23+
24+
TJsonDescribeReplication(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev)
25+
: TBase(viewer, ev)
26+
{
27+
AllowedMethods = {HTTP_METHOD_GET};
28+
}
29+
30+
static YAML::Node GetSwagger() {
31+
TSimpleYamlBuilder yaml({
32+
.Method = "get",
33+
.Tag = "viewer",
34+
.Summary = "Replication schema detailed information",
35+
.Description = "Returns detailed information about replication",
36+
});
37+
yaml.AddParameter({
38+
.Name = "database",
39+
.Description = "database name",
40+
.Type = "string",
41+
.Required = true,
42+
});
43+
yaml.AddParameter({
44+
.Name = "path",
45+
.Description = "schema path",
46+
.Type = "string",
47+
.Required = true,
48+
});
49+
yaml.AddParameter({
50+
.Name = "include_stats",
51+
.Description = "include stat flag",
52+
.Type = "bool",
53+
});
54+
yaml.AddParameter({
55+
.Name = "timeout",
56+
.Description = "timeout in ms",
57+
.Type = "integer",
58+
});
59+
yaml.AddParameter({
60+
.Name = "enums",
61+
.Description = "convert enums to strings",
62+
.Type = "boolean",
63+
});
64+
yaml.AddParameter({
65+
.Name = "ui64",
66+
.Description = "return ui64 as number",
67+
.Required = false,
68+
});
69+
yaml.SetResponseSchema(TProtoToYaml::ProtoToYamlSchema<Ydb::Replication::DescribeReplicationResult>());
70+
return yaml;
71+
}
72+
};
73+
74+
}

ydb/public/api/protos/ydb_scheme.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ message Entry {
6666
EXTERNAL_DATA_SOURCE = 19;
6767
VIEW = 20;
6868
RESOURCE_POOL = 21;
69+
TRANSFER = 23;
6970
}
7071

7172
// Name of scheme entry (dir2 of /dir1/dir2)

0 commit comments

Comments
 (0)