Skip to content

Commit 468b868

Browse files
authored
Merge 9495d53 into 16b2be5
2 parents 16b2be5 + 9495d53 commit 468b868

File tree

13 files changed

+253
-59
lines changed

13 files changed

+253
-59
lines changed

ydb/core/testlib/common_helper.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ void THelper::WaitForSchemeOperation(TActorId sender, ui64 txId) {
5353

5454
void THelper::StartScanRequest(const TString& request, const bool expectSuccess, TVector<THashMap<TString, NYdb::TValue>>* result) const {
5555
NYdb::NTable::TTableClient tClient(Server.GetDriver(),
56-
NYdb::NTable::TClientSettings().UseQueryCache(false).AuthToken("root@builtin"));
56+
NYdb::NTable::TClientSettings().UseQueryCache(false).AuthToken(AuthToken));
5757
auto expectation = expectSuccess;
5858
bool resultReady = false;
5959
TVector<THashMap<TString, NYdb::TValue>> rows;
@@ -109,7 +109,7 @@ void THelper::StartScanRequest(const TString& request, const bool expectSuccess,
109109

110110
void THelper::StartDataRequest(const TString& request, const bool expectSuccess, TString* result) const {
111111
NYdb::NTable::TTableClient tClient(Server.GetDriver(),
112-
NYdb::NTable::TClientSettings().UseQueryCache(false).AuthToken("root@builtin"));
112+
NYdb::NTable::TClientSettings().UseQueryCache(false).AuthToken(AuthToken));
113113
auto expectation = expectSuccess;
114114
bool resultReady = false;
115115
bool* rrPtr = &resultReady;
@@ -144,7 +144,7 @@ void THelper::StartDataRequest(const TString& request, const bool expectSuccess,
144144

145145
void THelper::StartSchemaRequestTableServiceImpl(const TString& request, const bool expectation, const bool waiting) const {
146146
NYdb::NTable::TTableClient tClient(Server.GetDriver(),
147-
NYdb::NTable::TClientSettings().UseQueryCache(false).AuthToken("root@builtin"));
147+
NYdb::NTable::TClientSettings().UseQueryCache(false).AuthToken(AuthToken));
148148

149149
std::shared_ptr<bool> rrPtr = std::make_shared<bool>(false);
150150
tClient.CreateSession().Subscribe([rrPtr, request, expectation](NThreading::TFuture<NYdb::NTable::TCreateSessionResult> f) {
@@ -171,7 +171,7 @@ void THelper::StartSchemaRequestTableServiceImpl(const TString& request, const b
171171

172172
void THelper::StartSchemaRequestQueryServiceImpl(const TString& request, const bool expectation, const bool waiting) const {
173173
NYdb::NQuery::TQueryClient qClient(Server.GetDriver(),
174-
NYdb::NQuery::TClientSettings().AuthToken("root@builtin"));
174+
NYdb::NQuery::TClientSettings().AuthToken(AuthToken));
175175

176176
std::shared_ptr<bool> rrPtr = std::make_shared<bool>(false);
177177
auto future = qClient.ExecuteQuery(request, NYdb::NQuery::TTxControl::NoTx());

ydb/core/testlib/common_helper.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ class TLoggerInit {
5454
};
5555

5656
class THelper {
57+
private:
58+
inline static const TString DefaultAuthToken = "root@builtin";
59+
YDB_ACCESSOR(TString, AuthToken, DefaultAuthToken);
60+
5761
protected:
5862
void WaitForSchemeOperation(TActorId sender, ui64 txId);
5963
void PrintResultSet(const NYdb::TResultSet& resultSet, NYson::TYsonWriter& writer) const;
@@ -73,6 +77,10 @@ class THelper {
7377
UseQueryService = use;
7478
}
7579

80+
void ResetAuthToken() {
81+
AuthToken = DefaultAuthToken;
82+
}
83+
7684
void DropTable(const TString& tablePath);
7785

7886
void StartScanRequest(const TString& request, const bool expectSuccess, TVector<THashMap<TString, NYdb::TValue>>* result) const;

ydb/services/metadata/manager/abstract.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,17 @@
44

55
#include <ydb/core/protos/kqp_physical.pb.h>
66
#include <ydb/core/tx/locks/sys_tables.h>
7+
78
#include <ydb/library/accessor/accessor.h>
89
#include <ydb/library/aclib/aclib.h>
9-
#include <ydb/library/conclusion/status.h>
10+
#include <ydb/library/actors/core/actorsystem.h>
1011
#include <ydb/library/conclusion/result.h>
11-
12+
#include <ydb/library/conclusion/status.h>
1213
#include <ydb/services/metadata/abstract/kqp_common.h>
1314
#include <ydb/services/metadata/abstract/parsing.h>
15+
#include <ydb/services/metadata/manager/modification.h>
1416

1517
#include <library/cpp/threading/future/core/future.h>
16-
#include <ydb/library/actors/core/actorsystem.h>
1718
#include <yql/essentials/sql/settings/translation_settings.h>
1819

1920
namespace NKikimr::NMetadata::NModifications {
@@ -168,6 +169,11 @@ class IObjectOperationsManager: public IOperationsManager {
168169
const TInternalModificationContext& context, const TAlterOperationContext& alterContext) const {
169170
return DoPrepareObjectsBeforeModification(std::move(patchedObjects), controller, context, alterContext);
170171
}
172+
173+
virtual std::vector<TModificationStage::TPtr> GetPreconditions(
174+
const std::vector<TObject>& /*objects*/, const IOperationsManager::TInternalModificationContext& /*context*/) const {
175+
return {};
176+
}
171177
};
172178

173179
class IObjectModificationCommand {

ydb/services/metadata/manager/alter.h

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ class TUpdateObjectActor: public TModificationActor<TObject> {
1515
using TBase = TModificationActor<TObject>;
1616
protected:
1717
virtual bool ProcessPreparedObjects(NInternal::TTableRecords&& records) const override {
18-
TBase::Register(new TUpdateObjectsActor<TObject>(std::move(records), TBase::UserToken,
19-
TBase::InternalController, TBase::SessionId, TBase::TransactionId, TBase::Context.GetExternalData().GetUserToken()));
18+
TBase::Register(new TUpdateObjectsActor<TObject>(std::move(records), TBase::UserToken, TBase::InternalController, TBase::SessionId,
19+
TBase::TransactionId, TBase::Context.GetExternalData().GetUserToken(), TBase::Preconditions));
2020
return true;
2121
}
2222

@@ -33,9 +33,8 @@ class TUpsertObjectActor: public TModificationActor<TObject> {
3333
using TBase = TModificationActor<TObject>;
3434
protected:
3535
virtual bool ProcessPreparedObjects(NInternal::TTableRecords&& records) const override {
36-
TBase::Register(new TUpsertObjectsActor<TObject>(std::move(records), TBase::UserToken,
37-
TBase::InternalController, TBase::SessionId, TBase::TransactionId,
38-
TBase::Context.GetExternalData().GetUserToken()));
36+
TBase::Register(new TUpsertObjectsActor<TObject>(std::move(records), TBase::UserToken, TBase::InternalController, TBase::SessionId,
37+
TBase::TransactionId, TBase::Context.GetExternalData().GetUserToken(), TBase::Preconditions));
3938
return true;
4039
}
4140

@@ -53,9 +52,8 @@ class TCreateObjectActor: public TModificationActor<TObject> {
5352
bool ExistingOk = false;
5453
protected:
5554
virtual bool ProcessPreparedObjects(NInternal::TTableRecords&& records) const override {
56-
TBase::Register(new TInsertObjectsActor<TObject>(std::move(records), TBase::UserToken,
57-
TBase::InternalController, TBase::SessionId, TBase::TransactionId,
58-
TBase::Context.GetExternalData().GetUserToken(), ExistingOk));
55+
TBase::Register(new TInsertObjectsActor<TObject>(std::move(records), TBase::UserToken, TBase::InternalController, TBase::SessionId,
56+
TBase::TransactionId, TBase::Context.GetExternalData().GetUserToken(), TBase::Preconditions, ExistingOk));
5957
return true;
6058
}
6159

@@ -103,8 +101,8 @@ class TDeleteObjectActor: public TModificationActor<TObject> {
103101
using TBase::TBase;
104102

105103
virtual bool ProcessPreparedObjects(NInternal::TTableRecords&& records) const override {
106-
TBase::Register(new TDeleteObjectsActor<TObject>(std::move(records), TBase::UserToken,
107-
TBase::InternalController, TBase::SessionId, TBase::TransactionId, TBase::Context.GetExternalData().GetUserToken()));
104+
TBase::Register(new TDeleteObjectsActor<TObject>(std::move(records), TBase::UserToken, TBase::InternalController, TBase::SessionId,
105+
TBase::TransactionId, TBase::Context.GetExternalData().GetUserToken(), TBase::Preconditions));
108106
return true;
109107
}
110108

ydb/services/metadata/manager/alter_impl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class TModificationActorImpl: public NActors::TActorBootstrapped<TModificationAc
5858
typename IObjectOperationsManager<TObject>::TPtr Manager;
5959
const IOperationsManager::TInternalModificationContext Context;
6060
std::vector<NInternal::TTableRecord> Patches;
61+
std::vector<TModificationStage::TPtr> Preconditions;
6162
NInternal::TTableRecords RestoreObjectIds;
6263
const NACLib::TUserToken UserToken = NACLib::TSystemUsers::Metadata();
6364
virtual bool PrepareRestoredObjects(std::vector<TObject>& objects) const = 0;
@@ -179,6 +180,7 @@ class TModificationActorImpl: public NActors::TActorBootstrapped<TModificationAc
179180
}
180181

181182
void Handle(typename TEvAlterPreparationFinished<TObject>::TPtr& ev) {
183+
Preconditions = Manager->GetPreconditions(ev->Get()->GetObjects(), Context);
182184
NInternal::TTableRecords records;
183185
records.InitColumns(Manager->GetSchema().GetYDBColumns());
184186
records.ReserveRows(ev->Get()->GetObjects().size());

ydb/services/metadata/manager/modification.h

Lines changed: 105 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,32 @@
1010

1111
namespace NKikimr::NMetadata::NModifications {
1212

13+
class TModificationStage {
14+
private:
15+
YDB_ACCESSOR_DEF(Ydb::Table::ExecuteDataQueryRequest, Request);
16+
17+
public:
18+
using TPtr = std::shared_ptr<TModificationStage>;
19+
20+
virtual TConclusionStatus HandleResult(const Ydb::Table::ExecuteQueryResult& /*result*/) const {
21+
return TConclusionStatus::Success();
22+
}
23+
24+
virtual TConclusionStatus HandleError(const NRequest::TEvRequestFailed& ev) const {
25+
return TConclusionStatus::Fail(ev.GetErrorMessage());
26+
}
27+
28+
void SetCommit() {
29+
Request.mutable_tx_control()->set_commit_tx(true);
30+
}
31+
32+
TModificationStage(Ydb::Table::ExecuteDataQueryRequest request)
33+
: Request(std::move(request)) {
34+
}
35+
36+
virtual ~TModificationStage() = default;
37+
};
38+
1339
template <class TObject>
1440
class TModifyObjectsActor: public NActors::TActorBootstrapped<TModifyObjectsActor<TObject>> {
1541
private:
@@ -19,17 +45,44 @@ class TModifyObjectsActor: public NActors::TActorBootstrapped<TModifyObjectsActo
1945
const TString TransactionId;
2046
const NACLib::TUserToken SystemUserToken;
2147
const std::optional<NACLib::TUserToken> UserToken;
48+
49+
void FillRequestSettings(Ydb::Table::ExecuteDataQueryRequest& request) {
50+
request.set_session_id(SessionId);
51+
request.mutable_tx_control()->set_tx_id(TransactionId);
52+
}
53+
54+
void AdvanceStage() {
55+
AFL_VERIFY(!Stages.empty());
56+
Stages.pop_front();
57+
if (Stages.size()) {
58+
TBase::Register(
59+
new NRequest::TYDBCallbackRequest<NRequest::TDialogYQLRequest>(Stages.front()->GetRequest(), SystemUserToken, TBase::SelfId()));
60+
} else {
61+
Controller->OnModificationFinished();
62+
TBase::PassAway();
63+
}
64+
}
65+
2266
protected:
23-
std::deque<NRequest::TDialogYQLRequest::TRequest> Requests;
67+
std::deque<TModificationStage::TPtr> Stages;
2468
NInternal::TTableRecords Objects;
2569
virtual Ydb::Table::ExecuteDataQueryRequest BuildModifyQuery() const = 0;
2670
virtual TString GetModifyType() const = 0;
71+
virtual TModificationStage::TPtr DoBuildRequestDirect(Ydb::Table::ExecuteDataQueryRequest query) const {
72+
return std::make_shared<TModificationStage>(std::move(query));
73+
}
74+
75+
void BuildPreconditionStages(const std::vector<TModificationStage::TPtr>& stages) {
76+
for (auto&& stage : stages) {
77+
FillRequestSettings(stage->MutableRequest());
78+
Stages.emplace_back(std::move(stage));
79+
}
80+
}
2781

2882
void BuildRequestDirect() {
2983
Ydb::Table::ExecuteDataQueryRequest request = BuildModifyQuery();
30-
request.set_session_id(SessionId);
31-
request.mutable_tx_control()->set_tx_id(TransactionId);
32-
Requests.emplace_back(std::move(request));
84+
FillRequestSettings(request);
85+
Stages.emplace_back(DoBuildRequestDirect(request));
3386
}
3487

3588
void BuildRequestHistory() {
@@ -42,31 +95,39 @@ class TModifyObjectsActor: public NActors::TActorBootstrapped<TModifyObjectsActo
4295
Objects.AddColumn(NInternal::TYDBColumn::UInt64("historyInstant"), NInternal::TYDBValue::UInt64(TActivationContext::Now().MicroSeconds()));
4396
Objects.AddColumn(NInternal::TYDBColumn::Utf8("historyAction"), NInternal::TYDBValue::Utf8(GetModifyType()));
4497
Ydb::Table::ExecuteDataQueryRequest request = Objects.BuildInsertQuery(TObject::GetBehaviour()->GetStorageHistoryTablePath());
45-
request.set_session_id(SessionId);
46-
request.mutable_tx_control()->set_tx_id(TransactionId);
47-
Requests.emplace_back(std::move(request));
98+
FillRequestSettings(request);
99+
Stages.emplace_back(std::make_shared<TModificationStage>(std::move(request)));
48100
}
49101

50-
void Handle(NRequest::TEvRequestResult<NRequest::TDialogYQLRequest>::TPtr& /*ev*/) {
51-
if (Requests.size()) {
52-
TBase::Register(new NRequest::TYDBCallbackRequest<NRequest::TDialogYQLRequest>(
53-
Requests.front(), SystemUserToken, TBase::SelfId()));
54-
Requests.pop_front();
55-
} else {
56-
Controller->OnModificationFinished();
102+
void Handle(NRequest::TEvRequestResult<NRequest::TDialogYQLRequest>::TPtr& ev) {
103+
const auto& operation = ev->Get()->GetResult().operation();
104+
AFL_VERIFY(operation.ready());
105+
106+
Ydb::Table::ExecuteQueryResult result;
107+
operation.result().UnpackTo(&result);
108+
109+
if (auto status = Stages.front()->HandleResult(result); status.IsFail()) {
110+
Controller->OnModificationProblem(status.GetErrorMessage());
57111
TBase::PassAway();
112+
return;
58113
}
114+
115+
AdvanceStage();
59116
}
60117

61-
virtual void Handle(NRequest::TEvRequestFailed::TPtr& ev) {
118+
void Handle(NRequest::TEvRequestFailed::TPtr& ev) {
62119
auto g = TBase::PassAwayGuard();
63-
Controller->OnModificationProblem("cannot execute yql request for " + GetModifyType() +
64-
" objects: " + ev->Get()->GetErrorMessage());
120+
if (auto status = Stages.front()->HandleError(*ev->Get()); status.IsFail()) {
121+
Controller->OnModificationProblem(status.GetErrorMessage());
122+
} else {
123+
Controller->OnModificationFinished();
124+
}
65125
}
66126

67127
public:
68-
TModifyObjectsActor(NInternal::TTableRecords&& objects, const NACLib::TUserToken& systemUserToken, IModificationObjectsController::TPtr controller, const TString& sessionId,
69-
const TString& transactionId, const std::optional<NACLib::TUserToken>& userToken)
128+
TModifyObjectsActor(NInternal::TTableRecords&& objects, const NACLib::TUserToken& systemUserToken,
129+
IModificationObjectsController::TPtr controller, const TString& sessionId, const TString& transactionId,
130+
const std::optional<NACLib::TUserToken>& userToken, const std::vector<TModificationStage::TPtr>& preconditions)
70131
: Controller(controller)
71132
, SessionId(sessionId)
72133
, TransactionId(transactionId)
@@ -75,6 +136,7 @@ class TModifyObjectsActor: public NActors::TActorBootstrapped<TModifyObjectsActo
75136
, Objects(std::move(objects))
76137

77138
{
139+
BuildPreconditionStages(preconditions);
78140
Y_ABORT_UNLESS(SessionId);
79141
}
80142

@@ -91,12 +153,10 @@ class TModifyObjectsActor: public NActors::TActorBootstrapped<TModifyObjectsActo
91153
TBase::Become(&TModifyObjectsActor::StateMain);
92154
BuildRequestDirect();
93155
BuildRequestHistory();
94-
Y_ABORT_UNLESS(Requests.size());
95-
Requests.back().mutable_tx_control()->set_commit_tx(true);
156+
Y_ABORT_UNLESS(Stages.size());
157+
Stages.back()->SetCommit();
96158

97-
TBase::Register(new NRequest::TYDBCallbackRequest<NRequest::TDialogYQLRequest>(
98-
Requests.front(), SystemUserToken, TBase::SelfId()));
99-
Requests.pop_front();
159+
TBase::Register(new NRequest::TYDBCallbackRequest<NRequest::TDialogYQLRequest>(Stages.front()->GetRequest(), SystemUserToken, TBase::SelfId()));
100160
}
101161
};
102162

@@ -148,6 +208,23 @@ class TDeleteObjectsActor: public TModifyObjectsActor<TObject> {
148208
using TBase::TBase;
149209
};
150210

211+
class TStageInsertObjects: public NModifications::TModificationStage {
212+
private:
213+
const bool ExistingOk;
214+
215+
public:
216+
TConclusionStatus HandleError(const NRequest::TEvRequestFailed& ev) const override {
217+
if (ExistingOk && ev.GetStatus() == Ydb::StatusIds::PRECONDITION_FAILED) {
218+
return TConclusionStatus::Success();
219+
}
220+
return TConclusionStatus::Fail(ev.GetErrorMessage());
221+
}
222+
223+
TStageInsertObjects(Ydb::Table::ExecuteDataQueryRequest request, const bool existingOk)
224+
: TModificationStage(std::move(request)), ExistingOk(existingOk) {
225+
}
226+
};
227+
151228
template <class TObject>
152229
class TInsertObjectsActor: public TModifyObjectsActor<TObject> {
153230
private:
@@ -161,19 +238,13 @@ class TInsertObjectsActor: public TModifyObjectsActor<TObject> {
161238
return "insert";
162239
}
163240

164-
void Handle(NRequest::TEvRequestFailed::TPtr& ev) override {
165-
if (ev->Get()->GetStatus() == Ydb::StatusIds::PRECONDITION_FAILED && ExistingOk) {
166-
NRequest::TDialogYQLRequest::TResponse resp;
167-
this->Send(this->SelfId(), new NRequest::TEvRequestResult<NRequest::TDialogYQLRequest>(std::move(resp)));
168-
this->Requests.clear(); // Remove history request
169-
return;
170-
}
171-
TBase::Handle(ev);
241+
TModificationStage::TPtr DoBuildRequestDirect(Ydb::Table::ExecuteDataQueryRequest query) const override {
242+
return std::make_shared<TStageInsertObjects>(std::move(query), ExistingOk);
172243
}
173244
public:
174245
TInsertObjectsActor(NInternal::TTableRecords&& objects, const NACLib::TUserToken& systemUserToken, IModificationObjectsController::TPtr controller, const TString& sessionId,
175-
const TString& transactionId, const std::optional<NACLib::TUserToken>& userToken, bool existingOk)
176-
: TBase(std::move(objects), systemUserToken, std::move(controller), sessionId, transactionId, userToken)
246+
const TString& transactionId, const std::optional<NACLib::TUserToken>& userToken, const std::vector<TModificationStage::TPtr>& preconditions, bool existingOk)
247+
: TBase(std::move(objects), systemUserToken, std::move(controller), sessionId, transactionId, userToken, preconditions)
177248
, ExistingOk(existingOk)
178249
{
179250
}

ydb/services/metadata/secret/checker_secret.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,31 @@ namespace NKikimr::NMetadata::NSecret {
88
void TSecretPreparationActor::StartChecker() {
99
Y_ABORT_UNLESS(Secrets);
1010
auto g = PassAwayGuard();
11-
for (auto&& i : Objects) {
11+
THashMap<TString, TString> secretNameToOwner;
12+
for (auto&& object : Objects) {
13+
if (Context.GetActivityType() == NModifications::IOperationsManager::EActivityType::Create ||
14+
Context.GetActivityType() == NModifications::IOperationsManager::EActivityType::Upsert) {
15+
const auto* findSecret = secretNameToOwner.FindPtr(object.GetSecretId());
16+
if (findSecret && *findSecret != object.GetOwnerUserId()) {
17+
Controller->OnPreparationProblem("cannot create multiple secrets with same id: " + object.GetSecretId());
18+
return;
19+
}
20+
}
1221
if (Context.GetActivityType() == NModifications::IOperationsManager::EActivityType::Alter) {
13-
if (!Secrets->GetSecrets().contains(i)) {
14-
Controller->OnPreparationProblem("secret " + i.GetSecretId() + " not found for alter");
22+
if (!Secrets->GetSecrets().contains(object)) {
23+
Controller->OnPreparationProblem("secret " + object.GetSecretId() + " not found for alter");
1524
return;
1625
}
1726
}
1827
for (auto&& sa : Secrets->GetAccess()) {
1928
if (Context.GetActivityType() == NModifications::IOperationsManager::EActivityType::Drop) {
20-
if (sa.GetOwnerUserId() == i.GetOwnerUserId() && sa.GetSecretId() == i.GetSecretId()) {
21-
Controller->OnPreparationProblem("secret " + i.GetSecretId() + " using in access for " + sa.GetAccessSID());
29+
if (sa.GetOwnerUserId() == object.GetOwnerUserId() && sa.GetSecretId() == object.GetSecretId()) {
30+
Controller->OnPreparationProblem("secret " + object.GetSecretId() + " using in access for " + sa.GetAccessSID());
2231
return;
2332
}
2433
}
2534
}
35+
secretNameToOwner.emplace(object.GetSecretId(), object.GetOwnerUserId());
2636
}
2737
Controller->OnPreparationFinished(std::move(Objects));
2838
}

0 commit comments

Comments
 (0)