Skip to content

Commit 0bc0896

Browse files
authored
Async replication: option handling (#7217)
1 parent 74f3150 commit 0bc0896

File tree

4 files changed

+80
-40
lines changed

4 files changed

+80
-40
lines changed

ydb/core/kqp/provider/yql_kikimr_exec.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -651,25 +651,25 @@ namespace {
651651

652652
if (dstSettings.ConnectionString && (dstSettings.Endpoint || dstSettings.Database)) {
653653
ctx.AddError(TIssue(ctx.GetPosition(pos),
654-
TStringBuilder() << "Connection string and Endpoint/Database are mutually exclusive"));
654+
"CONNECTION_STRING and ENDPOINT/DATABASE are mutually exclusive"));
655655
return false;
656656
}
657657

658658
if (dstSettings.OAuthToken && dstSettings.StaticCredentials) {
659659
ctx.AddError(TIssue(ctx.GetPosition(pos),
660-
TStringBuilder() << "Token and User/Password are mutually exclusive"));
660+
"TOKEN and USER/PASSWORD are mutually exclusive"));
661661
return false;
662662
}
663663

664664
if (const auto& x = dstSettings.OAuthToken; x && x->Token && x->TokenSecretName) {
665665
ctx.AddError(TIssue(ctx.GetPosition(pos),
666-
TStringBuilder() << "TOKEN and TOKEN_SECRET_NAME are mutually exclusive"));
666+
"TOKEN and TOKEN_SECRET_NAME are mutually exclusive"));
667667
return false;
668668
}
669669

670670
if (const auto& x = dstSettings.StaticCredentials; x && x->Password && x->PasswordSecretName) {
671671
ctx.AddError(TIssue(ctx.GetPosition(pos),
672-
TStringBuilder() << "PASSWORD and PASSWORD_SECRET_NAME are mutually exclusive"));
672+
"PASSWORD and PASSWORD_SECRET_NAME are mutually exclusive"));
673673
return false;
674674
}
675675

@@ -2097,21 +2097,21 @@ class TKiSinkCallableExecutionTransformer : public TAsyncCallbackTransformer<TKi
20972097
return SyncError();
20982098
}
20992099

2100-
if (!settings.Settings.ConnectionString && !settings.Settings.Endpoint) {
2100+
if (!settings.Settings.ConnectionString && (!settings.Settings.Endpoint || !settings.Settings.Database)) {
21012101
ctx.AddError(TIssue(ctx.GetPosition(createReplication.Pos()),
2102-
TStringBuilder() << "Neither Connection string nor Endpoint/Database are provided"));
2102+
"Neither CONNECTION_STRING nor ENDPOINT/DATABASE are provided"));
21032103
return SyncError();
21042104
}
21052105

2106-
if (!settings.Settings.OAuthToken && !settings.Settings.StaticCredentials) {
2106+
if (const auto& x = settings.Settings.StaticCredentials; x && !x->UserName) {
21072107
ctx.AddError(TIssue(ctx.GetPosition(createReplication.Pos()),
2108-
TStringBuilder() << "Neither Token nor User/Password are provided"));
2108+
"USER is not provided"));
21092109
return SyncError();
21102110
}
21112111

2112-
if (const auto& x = settings.Settings.StaticCredentials; x && (!x->UserName && x->Password || !x->UserName && x->PasswordSecretName)) {
2112+
if (const auto& x = settings.Settings.StaticCredentials; x && (!x->Password || !x->PasswordSecretName)) {
21132113
ctx.AddError(TIssue(ctx.GetPosition(createReplication.Pos()),
2114-
TStringBuilder() << "USER for PASSWORD or PASSWORD_SECRET_NAME are not provided"));
2114+
"PASSWORD or PASSWORD_SECRET_NAME are not provided"));
21152115
return SyncError();
21162116
}
21172117

ydb/core/kqp/ut/scheme/kqp_scheme_ut.cpp

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5701,130 +5701,147 @@ Y_UNIT_TEST_SUITE(KqpScheme) {
57015701
auto db = kikimr.GetTableClient();
57025702
auto session = db.CreateSession().GetValueSync().GetSession();
57035703

5704-
// connection string & endpoint/database are mutually exclusive
5704+
// negative
57055705
{
57065706
auto query = R"(
57075707
--!syntax_v1
57085708
CREATE ASYNC REPLICATION `/Root/replication` FOR
57095709
`/Root/table` AS `/Root/replica`
57105710
WITH (
5711-
CONNECTION_STRING = "grpc://localhost:2135/?database=/Root"
5711+
CONNECTION_STRING = "grpc://localhost:2135/?database=/Root",
57125712
ENDPOINT = "localhost:2135",
57135713
DATABASE = "/Root"
57145714
);
57155715
)";
57165716

57175717
const auto result = session.ExecuteSchemeQuery(query).GetValueSync();
57185718
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::GENERIC_ERROR, result.GetIssues().ToString());
5719+
UNIT_ASSERT_STRING_CONTAINS(result.GetIssues().ToOneLineString(), "CONNECTION_STRING and ENDPOINT/DATABASE are mutually exclusive");
57195720
}
57205721
{
57215722
auto query = R"(
57225723
--!syntax_v1
57235724
CREATE ASYNC REPLICATION `/Root/replication` FOR
57245725
`/Root/table` AS `/Root/replica`
57255726
WITH (
5726-
DATABASE = "/Root"
5727+
ENDPOINT = "localhost:2135"
57275728
);
57285729
)";
57295730

57305731
const auto result = session.ExecuteSchemeQuery(query).GetValueSync();
57315732
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::GENERIC_ERROR, result.GetIssues().ToString());
5733+
UNIT_ASSERT_STRING_CONTAINS(result.GetIssues().ToOneLineString(), "Neither CONNECTION_STRING nor ENDPOINT/DATABASE are provided");
57325734
}
5733-
5734-
// token & user/password are mutually exclusive
57355735
{
57365736
auto query = R"(
57375737
--!syntax_v1
57385738
CREATE ASYNC REPLICATION `/Root/replication` FOR
57395739
`/Root/table` AS `/Root/replica`
57405740
WITH (
5741-
TOKEN = "foo",
5742-
USER = "user",
5743-
PASSWORD = "bar"
5741+
DATABASE = "/Root"
57445742
);
57455743
)";
57465744

57475745
const auto result = session.ExecuteSchemeQuery(query).GetValueSync();
57485746
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::GENERIC_ERROR, result.GetIssues().ToString());
5747+
UNIT_ASSERT_STRING_CONTAINS(result.GetIssues().ToOneLineString(), "Neither CONNECTION_STRING nor ENDPOINT/DATABASE are provided");
57495748
}
57505749
{
57515750
auto query = R"(
57525751
--!syntax_v1
57535752
CREATE ASYNC REPLICATION `/Root/replication` FOR
57545753
`/Root/table` AS `/Root/replica`
57555754
WITH (
5756-
CONNECTION_STRING = "grpc://localhost:2135/?database=/Root"
5755+
CONNECTION_STRING = "grpc://localhost:2135/?database=/Root",
5756+
TOKEN = "foo",
5757+
USER = "user",
5758+
PASSWORD = "bar"
57575759
);
57585760
)";
57595761

57605762
const auto result = session.ExecuteSchemeQuery(query).GetValueSync();
57615763
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::GENERIC_ERROR, result.GetIssues().ToString());
5764+
UNIT_ASSERT_STRING_CONTAINS(result.GetIssues().ToOneLineString(), "TOKEN and USER/PASSWORD are mutually exclusive");
57625765
}
5763-
5764-
// token & token_secret_name are mutually exclusive
57655766
{
57665767
auto query = R"(
57675768
--!syntax_v1
57685769
CREATE ASYNC REPLICATION `/Root/replication` FOR
57695770
`/Root/table` AS `/Root/replica`
57705771
WITH (
5772+
CONNECTION_STRING = "grpc://localhost:2135/?database=/Root",
57715773
TOKEN = "foo",
57725774
TOKEN_SECRET_NAME = "bar"
57735775
);
57745776
)";
57755777

57765778
const auto result = session.ExecuteSchemeQuery(query).GetValueSync();
57775779
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::GENERIC_ERROR, result.GetIssues().ToString());
5780+
UNIT_ASSERT_STRING_CONTAINS(result.GetIssues().ToOneLineString(), "TOKEN and TOKEN_SECRET_NAME are mutually exclusive");
57785781
}
5779-
5780-
// password & password_secret_name are mutually exclusive
57815782
{
57825783
auto query = R"(
57835784
--!syntax_v1
57845785
CREATE ASYNC REPLICATION `/Root/replication` FOR
57855786
`/Root/table` AS `/Root/replica`
57865787
WITH (
5788+
CONNECTION_STRING = "grpc://localhost:2135/?database=/Root",
57875789
USER = "user",
5788-
PASSWORD = "bar"
5790+
PASSWORD = "bar",
57895791
PASSWORD_SECRET_NAME = "baz"
57905792
);
57915793
)";
57925794
const auto result = session.ExecuteSchemeQuery(query).GetValueSync();
57935795
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::GENERIC_ERROR, result.GetIssues().ToString());
5796+
UNIT_ASSERT_STRING_CONTAINS(result.GetIssues().ToOneLineString(), "PASSWORD and PASSWORD_SECRET_NAME are mutually exclusive");
57945797
}
5795-
5796-
// password set & user is not set
57975798
{
57985799
auto query = R"(
57995800
--!syntax_v1
58005801
CREATE ASYNC REPLICATION `/Root/replication` FOR
58015802
`/Root/table` AS `/Root/replica`
58025803
WITH (
5804+
CONNECTION_STRING = "grpc://localhost:2135/?database=/Root",
58035805
PASSWORD = "bar"
58045806
);
58055807
)";
58065808

58075809
const auto result = session.ExecuteSchemeQuery(query).GetValueSync();
58085810
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::GENERIC_ERROR, result.GetIssues().ToString());
5811+
UNIT_ASSERT_STRING_CONTAINS(result.GetIssues().ToOneLineString(), "USER is not provided");
58095812
}
5813+
{
5814+
auto query = R"(
5815+
--!syntax_v1
5816+
CREATE ASYNC REPLICATION `/Root/replication` FOR
5817+
`/Root/table` AS `/Root/replica`
5818+
WITH (
5819+
CONNECTION_STRING = "grpc://localhost:2135/?database=/Root",
5820+
USER = "user"
5821+
);
5822+
)";
58105823

5811-
// unsupported setting (STATE) in CREATE
5824+
const auto result = session.ExecuteSchemeQuery(query).GetValueSync();
5825+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::GENERIC_ERROR, result.GetIssues().ToString());
5826+
UNIT_ASSERT_STRING_CONTAINS(result.GetIssues().ToOneLineString(), "PASSWORD or PASSWORD_SECRET_NAME are not provided");
5827+
}
58125828
{
58135829
auto query = R"(
58145830
--!syntax_v1
58155831
CREATE ASYNC REPLICATION `/Root/replication` FOR
58165832
`/Root/table` AS `/Root/replica`
58175833
WITH (
58185834
CONNECTION_STRING = "grpc://localhost:2135/?database=/Root",
5819-
TOKEN = "root@builtin",
58205835
STATE = "DONE"
58215836
);
58225837
)";
58235838

58245839
const auto result = session.ExecuteSchemeQuery(query).GetValueSync();
58255840
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::GENERIC_ERROR, result.GetIssues().ToString());
5841+
UNIT_ASSERT_STRING_CONTAINS(result.GetIssues().ToOneLineString(), "STATE is not supported in CREATE");
58265842
}
58275843

5844+
// positive
58285845
{
58295846
auto query = R"(
58305847
--!syntax_v1
@@ -5838,17 +5855,14 @@ Y_UNIT_TEST_SUITE(KqpScheme) {
58385855
auto result = session.ExecuteSchemeQuery(query).GetValueSync();
58395856
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
58405857
}
5841-
5842-
// ok
58435858
{
58445859
auto query = Sprintf(R"(
58455860
--!syntax_v1
58465861
CREATE ASYNC REPLICATION `/Root/replication` FOR
58475862
`/Root/table` AS `/Root/replica`
58485863
WITH (
58495864
ENDPOINT = "%s",
5850-
DATABASE = "/Root",
5851-
TOKEN = "root@builtin"
5865+
DATABASE = "/Root"
58525866
);
58535867
)", kikimr.GetEndpoint().c_str());
58545868

@@ -6080,7 +6094,6 @@ Y_UNIT_TEST_SUITE(KqpScheme) {
60806094
}
60816095
}
60826096

6083-
60846097
// Connection string and Endpoint/Database are mutually exclusive
60856098
{
60866099
auto query = R"(
@@ -6095,7 +6108,7 @@ Y_UNIT_TEST_SUITE(KqpScheme) {
60956108

60966109
const auto result = session.ExecuteSchemeQuery(query).GetValueSync();
60976110
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::GENERIC_ERROR, result.GetIssues().ToString());
6098-
UNIT_ASSERT_STRING_CONTAINS(result.GetIssues().ToOneLineString(), "Connection string and Endpoint/Database are mutually exclusive");
6111+
UNIT_ASSERT_STRING_CONTAINS(result.GetIssues().ToOneLineString(), "CONNECTION_STRING and ENDPOINT/DATABASE are mutually exclusive");
60996112
}
61006113

61016114
// alter connection params
@@ -6152,7 +6165,7 @@ Y_UNIT_TEST_SUITE(KqpScheme) {
61526165

61536166
const auto result = session.ExecuteSchemeQuery(query).GetValueSync();
61546167
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::GENERIC_ERROR, result.GetIssues().ToString());
6155-
UNIT_ASSERT_STRING_CONTAINS(result.GetIssues().ToOneLineString(), "Token and User/Password are mutually exclusive");
6168+
UNIT_ASSERT_STRING_CONTAINS(result.GetIssues().ToOneLineString(), "TOKEN and USER/PASSWORD are mutually exclusive");
61566169
}
61576170

61586171
// TOKEN and TOKEN_SECRET_NAME are mutually exclusive
@@ -6336,8 +6349,7 @@ Y_UNIT_TEST_SUITE(KqpScheme) {
63366349
`/Root/table` AS `/Root/replica`
63376350
WITH (
63386351
ENDPOINT = "%s",
6339-
DATABASE = "/Root",
6340-
TOKEN = "root@builtin"
6352+
DATABASE = "/Root"
63416353
);
63426354
)", kikimr.GetEndpoint().c_str());
63436355

@@ -6395,8 +6407,7 @@ Y_UNIT_TEST_SUITE(KqpScheme) {
63956407
`/Root/table` AS `/Root/replica`
63966408
WITH (
63976409
ENDPOINT = "%s",
6398-
DATABASE = "/Root",
6399-
TOKEN = "root@builtin"
6410+
DATABASE = "/Root"
64006411
);
64016412
)", kikimr.GetEndpoint().c_str());
64026413

@@ -6450,7 +6461,7 @@ Y_UNIT_TEST_SUITE(KqpScheme) {
64506461
CREATE ASYNC REPLICATION `/Root/replication` FOR
64516462
`/Root/table` AS `/Root/replica`
64526463
WITH (
6453-
%s, TOKEN = "root@builtin"
6464+
%s
64546465
);
64556466
)", connectionParam.c_str());
64566467

ydb/core/tx/schemeshard/schemeshard__operation_create_replication.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,10 @@ class TCreateReplication: public TSubOperation {
334334
parentPath->IncAliveChildren();
335335
parentPath.DomainInfo()->IncPathsInside();
336336

337+
if (desc.GetConfig().GetSrcConnectionParams().GetCredentialsCase() == NKikimrReplication::TConnectionParams::CREDENTIALS_NOT_SET) {
338+
desc.MutableConfig()->MutableSrcConnectionParams()->MutableOAuthToken()->SetToken(BUILTIN_ACL_ROOT);
339+
}
340+
337341
desc.MutableState()->MutableStandBy();
338342
auto replication = TReplicationInfo::Create(std::move(desc));
339343
context.SS->Replications[path->PathId] = replication;

ydb/core/tx/schemeshard/ut_replication/ut_replication.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,31 @@ Y_UNIT_TEST_SUITE(TReplicationTests) {
143143
}
144144
}
145145

146+
Y_UNIT_TEST(CreateWithoutCredentials) {
147+
TTestBasicRuntime runtime;
148+
TTestEnv env(runtime, TTestEnvOptions().InitYdbDriver(true));
149+
ui64 txId = 100;
150+
151+
SetupLogging(runtime);
152+
153+
TestCreateReplication(runtime, ++txId, "/MyRoot", R"(
154+
Name: "Replication"
155+
Config {
156+
Specific {
157+
Targets {
158+
SrcPath: "/MyRoot1/Table"
159+
DstPath: "/MyRoot2/Table"
160+
}
161+
}
162+
}
163+
)");
164+
env.TestWaitNotification(runtime, txId);
165+
166+
const auto desc = DescribePath(runtime, "/MyRoot/Replication");
167+
const auto& params = desc.GetPathDescription().GetReplicationDescription().GetConfig().GetSrcConnectionParams();
168+
UNIT_ASSERT_VALUES_UNEQUAL("root@builtin", params.GetOAuthToken().GetToken());
169+
}
170+
146171
Y_UNIT_TEST(Alter) {
147172
TTestBasicRuntime runtime;
148173
TTestEnv env(runtime, TTestEnvOptions().InitYdbDriver(true));

0 commit comments

Comments
 (0)