From dc3cb905ecb7135cd731d206a60d4d870145d004 Mon Sep 17 00:00:00 2001 From: Bulat Date: Fri, 28 Mar 2025 18:21:46 +0000 Subject: [PATCH 01/13] Refactor includes to YDB C++ SDK for ydb/apps and ydb/public (#15632) --- .../ydb-cpp-sdk/client/extensions/solomon_stats/README.md | 6 +++--- src/api/protos/ydb_monitoring.proto | 7 +++++++ src/client/topic/ut/ut_utils/trace.h | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/include/ydb-cpp-sdk/client/extensions/solomon_stats/README.md b/include/ydb-cpp-sdk/client/extensions/solomon_stats/README.md index b4e2ebb179..eb60778b02 100644 --- a/include/ydb-cpp-sdk/client/extensions/solomon_stats/README.md +++ b/include/ydb-cpp-sdk/client/extensions/solomon_stats/README.md @@ -32,8 +32,8 @@ After creating NYdb::TDriver you need to add Solomon Monitoring extension. If yo > **Important**: you must plug in monitoring before driver creation. ```cl -#include -#include +#include +#include ... @@ -65,7 +65,7 @@ Implementing NMonitoring::IMetricRegistry provides more flexibility. You can del Select a method which is right for you: ```cl -#include +#include ... diff --git a/src/api/protos/ydb_monitoring.proto b/src/api/protos/ydb_monitoring.proto index 2e708d4a5b..e012c61b90 100644 --- a/src/api/protos/ydb_monitoring.proto +++ b/src/api/protos/ydb_monitoring.proto @@ -29,6 +29,7 @@ message SelfCheckRequest { uint32 maximum_level = 4; // maximum level of issues to return bool do_not_cache = 5; // by default database health state is taken from metadata cache; this option can be used to force bypassing that cache bool merge_records = 6; // combine similar records with similar status, message and level into one issue + bool return_hints = 7; // return hints for common problems } message SelfCheckResponse { @@ -163,10 +164,16 @@ message LocationComputeTablet { uint32 count = 3; } +message LocationComputeSchema { + string type = 1; + string path = 2; +} + message LocationCompute { LocationNode node = 1; LocationComputePool pool = 2; LocationComputeTablet tablet = 3; + LocationComputeSchema schema = 4; } message LocationDatabase { diff --git a/src/client/topic/ut/ut_utils/trace.h b/src/client/topic/ut/ut_utils/trace.h index 8035e4ff80..91d11eefb8 100644 --- a/src/client/topic/ut/ut_utils/trace.h +++ b/src/client/topic/ut/ut_utils/trace.h @@ -1,6 +1,6 @@ #pragma once -#include "src/client/topic/common/trace_lazy.h" +#include #include "library/cpp/logger/backend.h" #include "library/cpp/logger/record.h" From 931b6d213f0c4bb36683e370c6c0efb98eb68f4f Mon Sep 17 00:00:00 2001 From: Bulat Date: Fri, 28 Mar 2025 18:23:05 +0000 Subject: [PATCH 02/13] [C++ SDK] Changed names for resources (#15691) --- src/client/resources/ydb_ca.cpp | 4 ++-- src/client/resources/ydb_resources.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/client/resources/ydb_ca.cpp b/src/client/resources/ydb_ca.cpp index 96ff0618bb..8da95f1dbe 100644 --- a/src/client/resources/ydb_ca.cpp +++ b/src/client/resources/ydb_ca.cpp @@ -5,7 +5,7 @@ namespace NYdb::inline V3 { std::string GetRootCertificate() { - return NResource::Find("ydb_root_ca_v3.pem"); + return NResource::Find("ydb_root_ca_dev.pem"); } -} // namespace NYdb \ No newline at end of file +} // namespace NYdb diff --git a/src/client/resources/ydb_resources.cpp b/src/client/resources/ydb_resources.cpp index 22a7bdd39a..1b3edb7f5b 100644 --- a/src/client/resources/ydb_resources.cpp +++ b/src/client/resources/ydb_resources.cpp @@ -29,7 +29,7 @@ const char* YDB_CLIENT_CAPABILITY_SESSION_BALANCER = "session-balancer"; std::string GetSdkSemver() { - return NResource::Find("ydb_sdk_version_v3.txt"); + return NResource::Find("ydb_sdk_version_dev.txt"); } } // namespace NYdb From 99de01fb587bf8b445d603ee333684d812a5d4da Mon Sep 17 00:00:00 2001 From: Aleksey Myasnikov Date: Fri, 28 Mar 2025 18:24:45 +0000 Subject: [PATCH 03/13] Fixed BackoffTimeout_ overflow (#15874) --- src/api/protos/draft/fq.proto | 5 +++++ src/api/protos/draft/ydb_maintenance.proto | 8 ++++++++ src/client/iam/common/iam.h | 2 +- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/api/protos/draft/fq.proto b/src/api/protos/draft/fq.proto index 16103753b9..84177a909b 100644 --- a/src/api/protos/draft/fq.proto +++ b/src/api/protos/draft/fq.proto @@ -431,11 +431,16 @@ message ServiceAccountAuth { string id = 1 [(Ydb.length).le = 1024]; } +message TokenAuth { + string token = 1 [(Ydb.length).le = 1024, (Ydb.sensitive) = true]; +} + message IamAuth { oneof identity { CurrentIAMTokenAuth current_iam = 1; ServiceAccountAuth service_account = 2; NoneAuth none = 3; + TokenAuth token = 4; } } diff --git a/src/api/protos/draft/ydb_maintenance.proto b/src/api/protos/draft/ydb_maintenance.proto index d6c754d807..477d0c2127 100644 --- a/src/api/protos/draft/ydb_maintenance.proto +++ b/src/api/protos/draft/ydb_maintenance.proto @@ -182,6 +182,10 @@ message MaintenanceTaskResult { repeated ActionGroupStates action_group_states = 2; // Try again after this deadline. Specified if there are no performed actions. optional google.protobuf.Timestamp retry_after = 3; + // The time when the mainteance task was created. + google.protobuf.Timestamp create_time = 4; + // The last time when the mainteance task was refreshed. Initially equals to create_time. + google.protobuf.Timestamp last_refresh_time = 5; } message MaintenanceTaskResponse { @@ -197,6 +201,10 @@ message GetMaintenanceTaskRequest { message GetMaintenanceTaskResult { MaintenanceTaskOptions task_options = 1; repeated ActionGroupStates action_group_states = 2; + // The time when the mainteance task was created. + google.protobuf.Timestamp create_time = 3; + // The last time when the mainteance task was refreshed. Initially equals to create_time. + google.protobuf.Timestamp last_refresh_time = 4; } message GetMaintenanceTaskResponse { diff --git a/src/client/iam/common/iam.h b/src/client/iam/common/iam.h index 22bd10e5fc..140ac966dd 100644 --- a/src/client/iam/common/iam.h +++ b/src/client/iam/common/iam.h @@ -126,7 +126,7 @@ class TGrpcIamCredentialsProvider : public ICredentialsProvider { RequestInflight_ = false; sleepDuration = std::min(BackoffTimeout_, BACKOFF_MAX); - BackoffTimeout_ *= 2; + BackoffTimeout_ = std::min(BackoffTimeout_ * 2, BACKOFF_MAX); } Sleep(sleepDuration); From 4256145d366864761dbd8124ec8cba0f87098495 Mon Sep 17 00:00:00 2001 From: Alek5andr-Kotov Date: Fri, 28 Mar 2025 18:26:08 +0000 Subject: [PATCH 04/13] An empty list of consumers for the background partition (#15889) --- .../resources/topic_A_partition_0_v24-4-2.dat | Bin 0 -> 2638 bytes .../resources/topic_A_partition_1_v24-4-2.dat | Bin 0 -> 2158 bytes src/client/topic/ut/topic_to_table_ut.cpp | 63 ++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 src/client/topic/ut/resources/topic_A_partition_0_v24-4-2.dat create mode 100644 src/client/topic/ut/resources/topic_A_partition_1_v24-4-2.dat diff --git a/src/client/topic/ut/resources/topic_A_partition_0_v24-4-2.dat b/src/client/topic/ut/resources/topic_A_partition_0_v24-4-2.dat new file mode 100644 index 0000000000000000000000000000000000000000..410dfcefc041bf9d9e73b210d34217f02c392b01 GIT binary patch literal 2638 zcmeHINt2>T6rOYain$vTLP=SA=)+5P5F}YtxKsc_vWTF9s4+i&l3KdUj_#R>n29-! z5vFMpyd}ToX$<|a!@~TEcTH^;5?VWfyT-nDoSp!n2iY0bVYz zAlpst^;Jbo!`W^{ezxliRGrIK)^s0fEgMZXgc~h7M~`)p2*^xVcyn zv?0Ls3p8Smnr12*yt%RZ#esh=^F5!b+fgia|!SEL$a@IpU$2x~jm+b_pSBYMM0+ zltWUQ2N73!7&(UPf~#fV^FCX^+NJeHm~yb1 zZG|k7xy)h}M=ca&N6|vlos#TWMLIB!7_&ON35{0STW+Nlo_k#D@~#sSaGnd%viQjb z#y&ad*Djq;&b!SegG*svwpZKDaA~}?dymVXz?^7VUr=fd;E4C&$d!pRBJ6cJ;<_ib z>1#(3d(N(b!u}WFFn zK&}X&I;j~;x4b!K=Bn+DZPD_QIy9S|DKK`)Tn&6N1(!9XOuayz$Cdh&E6jPvqrk#} zprBgb)JYOebiCT=xYpLD9PmsW6cL`Emq7frDEW>imLeWG<;0HG>y>ku`8)0!U-PP! zrPYzkMUtNjCiWk3qUjZ%a^9Z3?KisW&ZebHKD3yyi6&7k8Uvf(DBk??ic*!FP9aHN z$g%F4mwfv&xu>(On3L0Nz>7(fS9hSsFz}mR3e_o)VGm^3fgl-xOr#ToM2>Y_L~_lI zc^>haWPR`jy~ew%_^p|7VoxyLYJwQWV)6fWb@ zI9+=pc<~8=Pk%vwx=l*SE9o7q5qgs(wIy!>(BF8^$?40@6Nm{0dn(wnI+tB`ruMFzPP66n(U#|!Pw&f#cRzwiLOold6XsiUdZS*~*CP5W%EZ`bvk#CHt87t*9cb zE1AQuu-D61b=zcHjW}bGgQbqRU>2&kfDU(TG3%5%m1t67C* zcT?fZ!%KU~_i23(LV$KlZJ0{MEUhFz9H!DRodz)x=zUdvw;VcjMSkVlt?RM^X2Qs` zJl&)>2@qg@v_V;c*G^+6?LjSXTp?B)V;!<#|LmV8gyWt*CUB-2&BYv;`iWmZlRbN1 zZERSz-_w*Pvz6~=ZSrdN_hAKGzT?V literal 0 HcmV?d00001 diff --git a/src/client/topic/ut/resources/topic_A_partition_1_v24-4-2.dat b/src/client/topic/ut/resources/topic_A_partition_1_v24-4-2.dat new file mode 100644 index 0000000000000000000000000000000000000000..32775aa04b484274456b0d809870a9398e7c4bc1 GIT binary patch literal 2158 zcmeHIOOL8Z6rOeeirJe9_~>q3^x_m0Sb%7usIW1pP#|wb5p#e16y3KUc5Wt_%w$$W z4DzZ|^_}lgk@$Xef2T>2n+FB0=I&y(ghSjX0HD=?5l{?3B>>`>C}jql56+LIsPnnR ztY#a-gVxsRz83pds3_B#@j}PJEo}=SN)>(!6nJ?o@srvX_Dm}mMbDJNqF`Y5DOur2 zw31q32}IAsI*Yr@Kr~dJN1^(sGS>}93a{$UK z6xzb!6Gx~hp72C6*R$FvrRO-xq>$``@$g7r9^_9*n~zDpT)aK}eARus{Bb`!odqCG z0FWyPox{~ukWI6ywgG{3_Ky7_0DJ8O{{%QB6kEJ4lz?Q1dgKmQf0)dp*=B$xqBL=YuOlFZ>~gd__&H6mtH;}8o?zZ1f2*A zOGlf9^I$#Q(`q103q`o@8*35L7+x{IJWM`2_%CzwrSkdLtb50Kf3f4NBi>HHob3>Z zF24(?tc<-`bNy`i@E~IMq^+M;$7u~9UxkhktZWSS?u5YM|DZqK`mwTX6|_R=%^Zlo zFaYWsC(WuTml|-wz?2sYI--%Mdo#;a7o5C>mDj9M$!zY*TEP-Ua)HYp#e4)m%o25b zk=^8LB-q>DqI(n55T*);@p|6y^(i5UET9-fRX$j zVXB$f1%bUIQKx-lG`will*58%UN|1*|$VI z{{@b}X^_qLRsV01|HL9+lCJpemCn>Zojm4m*fBpBn`po3-TTL#35mnE6)?rU8n!zw yR}l9O@J$5)aofv^3EZ9hd7&7l|EjXYzFKG#|denb4g4J74_6to;+}@}{o< literal 0 HcmV?d00001 diff --git a/src/client/topic/ut/topic_to_table_ut.cpp b/src/client/topic/ut/topic_to_table_ut.cpp index 50e534204c..17bf94337b 100644 --- a/src/client/topic/ut/topic_to_table_ut.cpp +++ b/src/client/topic/ut/topic_to_table_ut.cpp @@ -16,6 +16,7 @@ #include #include +#include namespace NYdb::NTopic::NTests { @@ -150,6 +151,9 @@ class TFixture : public NUnitTest::TBaseFixture { void RestartLongTxService(); void RestartPQTablet(const TString& topicPath, ui32 partition); void DumpPQTabletKeys(const TString& topicName, ui32 partition); + void PQTabletPrepareFromResource(const TString& topicPath, + ui32 partitionId, + const TString& resourceName); void DeleteSupportivePartition(const TString& topicName, ui32 partition); @@ -1857,6 +1861,51 @@ void TFixture::DumpPQTabletKeys(const TString& topicName) } } +void TFixture::PQTabletPrepareFromResource(const TString& topicPath, + ui32 partitionId, + const TString& resourceName) +{ + auto& runtime = Setup->GetRuntime(); + TActorId edge = runtime.AllocateEdgeActor(); + ui64 tabletId = GetTopicTabletId(edge, "/Root/" + topicPath, partitionId); + + auto request = MakeHolder(); + size_t count = 0; + + for (TStringStream stream(NResource::Find(resourceName)); true; ++count) { + TString key, encoded; + + if (!stream.ReadTo(key, ' ')) { + break; + } + encoded = stream.ReadLine(); + + auto decoded = Base64Decode(encoded); + TStringInput decodedStream(decoded); + TBZipDecompress decompressor(&decodedStream); + + auto* cmd = request->Record.AddCmdWrite(); + cmd->SetKey(key); + cmd->SetValue(decompressor.ReadAll()); + } + + runtime.SendToPipe(tabletId, edge, request.Release(), 0, GetPipeConfigWithRetries()); + + TAutoPtr handle; + auto* response = runtime.GrabEdgeEvent(handle); + UNIT_ASSERT(response); + UNIT_ASSERT(response->Record.HasStatus()); + UNIT_ASSERT_EQUAL(response->Record.GetStatus(), NMsgBusProxy::MSTATUS_OK); + + UNIT_ASSERT_VALUES_EQUAL(response->Record.WriteResultSize(), count); + + for (size_t i = 0; i < response->Record.WriteResultSize(); ++i) { + const auto &result = response->Record.GetWriteResult(i); + UNIT_ASSERT(result.HasStatus()); + UNIT_ASSERT_EQUAL(result.GetStatus(), NKikimrProto::OK); + } +} + void TFixture::TestTheCompletionOfATransaction(const TTransactionCompletionTestDescription& d) { for (auto& topic : d.Topics) { @@ -3207,6 +3256,20 @@ Y_UNIT_TEST_F(Transactions_Conflict_On_SeqNo, TFixture) UNIT_ASSERT_VALUES_UNEQUAL(successCount, TXS_COUNT); } +Y_UNIT_TEST_F(The_Transaction_Starts_On_One_Version_And_Ends_On_The_Other, TFixture) +{ + // In the test, we check the compatibility between versions `24-4-2` and `24-4-*/25-1-*`. To do this, the data + // obtained on the `24-4-2` version is loaded into the PQ tablets. + + CreateTopic("topic_A", TEST_CONSUMER, 2); + + PQTabletPrepareFromResource("topic_A", 0, "topic_A_partition_0_v24-4-2.dat"); + PQTabletPrepareFromResource("topic_A", 1, "topic_A_partition_1_v24-4-2.dat"); + + RestartPQTablet("topic_A", 0); + RestartPQTablet("topic_A", 1); +} + } } From 42d628d60ba6d2899405a5d7d601a125a535aa1f Mon Sep 17 00:00:00 2001 From: Aleksey Myasnikov Date: Fri, 28 Mar 2025 18:26:42 +0000 Subject: [PATCH 05/13] added GetParameterTypes() to TDataQuery (#16095) --- include/ydb-cpp-sdk/client/table/table.h | 1 + src/api/protos/ydb_export.proto | 46 +++++++++++++++++++++-- src/api/protos/ydb_import.proto | 47 ++++++++++++++++++------ src/api/protos/ydb_scheme.proto | 1 + src/client/table/table.cpp | 8 ++++ 5 files changed, 88 insertions(+), 15 deletions(-) diff --git a/include/ydb-cpp-sdk/client/table/table.h b/include/ydb-cpp-sdk/client/table/table.h index e26c6ec67f..5ca46f7c82 100644 --- a/include/ydb-cpp-sdk/client/table/table.h +++ b/include/ydb-cpp-sdk/client/table/table.h @@ -1955,6 +1955,7 @@ class TDataQuery { const std::string& GetId() const; const std::optional& GetText() const; TParamsBuilder GetParamsBuilder() const; + std::map GetParameterTypes() const; TAsyncDataQueryResult Execute(const TTxControl& txControl, const TExecDataQuerySettings& settings = TExecDataQuerySettings()); diff --git a/src/api/protos/ydb_export.proto b/src/api/protos/ydb_export.proto index 189c322e03..f8f3a8e7f0 100644 --- a/src/api/protos/ydb_export.proto +++ b/src/api/protos/ydb_export.proto @@ -1,6 +1,7 @@ syntax = "proto3"; option cc_enable_arenas = true; +import "src/api/protos/annotations/sensitive.proto"; import "src/api/protos/annotations/validation.proto"; import "src/api/protos/ydb_operation.proto"; @@ -86,15 +87,19 @@ message ExportToS3Settings { }; message Item { - // Database path to a table to be exported + // Database path to a table/directory to be exported string source_path = 1 [(required) = true]; /* Tables are exported to one or more S3 objects. The object name begins with 'destination_prefix'. This prefix will be followed by '/data_PartNumber', where 'PartNumber' represents the index of the part, starting at zero. + Not required if the default `destination_prefix` is set. + If not specified, actual S3 path is the default `destination_prefix` concatenated with: + * The object path relative to the global `source_path` for a non-encrypted export + * The anonymized path for an encrypted export */ - string destination_prefix = 2 [(required) = true]; + string destination_prefix = 2; } string endpoint = 1 [(required) = true]; @@ -102,7 +107,7 @@ message ExportToS3Settings { string bucket = 3 [(required) = true]; string access_key = 4 [(required) = true]; string secret_key = 5 [(required) = true]; - repeated Item items = 6 [(size).ge = 1]; + repeated Item items = 6; string description = 7 [(length).le = 128]; uint32 number_of_retries = 8; StorageClass storage_class = 9; @@ -120,6 +125,20 @@ message ExportToS3Settings { // details: https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html // it is especially useful for custom s3 implementations bool disable_virtual_addressing = 12; + + // Database root if not provided. + // All object names are calculated and written relative to this path. + string source_path = 13; + + // A default S3 path prefix for all export items. + // When specified, export writes SchemaMapping file with the list of objects. + // Must be provided for an encrypted backup. + string destination_prefix = 14; + + // Settings for data encryption. + // If encryption_settings field is not specified, + // the resulting data will not be encrypted. + EncryptionSettings encryption_settings = 15; } message ExportToS3Result { @@ -141,3 +160,24 @@ message ExportToS3Response { // operation.metadata = ExportToS3Metadata Ydb.Operations.Operation operation = 1; } + +// Export encryption settings +// Don't specify this struct for unencrypted exports +message EncryptionSettings { + // Algorithm for export encryption. + // Not required in case of import/list operation. + // Currently the following algorithms are supported: + // AES-128-GCM + // AES-256-GCM + // ChaCha20-Poly1305 + string encryption_algorithm = 1; + + oneof Key { + SymmetricKey symmetric_key = 2; + } + + message SymmetricKey { + // This key will be used for data encryption + bytes key = 1 [(Ydb.sensitive) = true]; + } +} diff --git a/src/api/protos/ydb_import.proto b/src/api/protos/ydb_import.proto index c7f7b586ea..3e21023525 100644 --- a/src/api/protos/ydb_import.proto +++ b/src/api/protos/ydb_import.proto @@ -2,6 +2,7 @@ syntax = "proto3"; option cc_enable_arenas = true; import "src/api/protos/annotations/validation.proto"; +import "src/api/protos/ydb_export.proto"; import "src/api/protos/ydb_operation.proto"; import "google/protobuf/timestamp.proto"; @@ -39,17 +40,25 @@ message ImportFromS3Settings { } message Item { - /* YDB tables in S3 are stored in one or more objects (see ydb_export.proto). - The object name begins with 'source_prefix'. - This prefix is followed by: - * '/data_PartNumber', where 'PartNumber' represents the index of the part, starting at zero; - * '/scheme.pb' - object with information about scheme, indexes, etc; - * '/permissions.pb' - object with information about ACL and owner. - */ - string source_prefix = 1 [(required) = true]; - - // Database path to a table to import to. - string destination_path = 2 [(required) = true]; + oneof Source { + /* YDB database objects in S3 are stored in one or more S3 objects (see ydb_export.proto). + The S3 object name begins with a prefix, followed by: + * '/data_PartNumber', where 'PartNumber' represents the index of the part, starting at zero; + * '/scheme.pb' - object with information about scheme, indexes, etc; + * '/permissions.pb' - object with information about ACL and owner. + */ + + // The S3 object prefix can be either provided explicitly + string source_prefix = 1; + + // Or, if the export contains the database objects list, you may specify the database object name, and the S3 prefix will be looked up in the database objects list by the import procedure + string source_path = 3; + } + + // Database path to a database object to import the item to + // Resolved relative to the default destination_path + // May be omitted if the item's source_path is specified, in this case will be taken equal to it + string destination_path = 2; } string endpoint = 1 [(required) = true]; @@ -57,7 +66,7 @@ message ImportFromS3Settings { string bucket = 3 [(required) = true]; string access_key = 4 [(required) = true]; string secret_key = 5 [(required) = true]; - repeated Item items = 6 [(size).ge = 1]; + repeated Item items = 6; // Empty collection means import of all export objects string description = 7 [(length).le = 128]; uint32 number_of_retries = 8; @@ -76,6 +85,20 @@ message ImportFromS3Settings { // Skip checksum validation during import bool skip_checksum_validation = 12; + + // A default path prefix for all items, + // determines that the import works with the list of objects in the SchemaMapping file. + // Must be provided to import an encrypted export. + string source_prefix = 13; + + // Destination path to restore paths inside database + // Default value is database root + string destination_path = 14; + + // Settings how data is encrypted. + // If encryption_settings field is not specified, + // the resulting data is considered not encrypted. + Ydb.Export.EncryptionSettings encryption_settings = 15; } message ImportFromS3Result { diff --git a/src/api/protos/ydb_scheme.proto b/src/api/protos/ydb_scheme.proto index 679c95b48a..2b172e9590 100644 --- a/src/api/protos/ydb_scheme.proto +++ b/src/api/protos/ydb_scheme.proto @@ -66,6 +66,7 @@ message Entry { EXTERNAL_DATA_SOURCE = 19; VIEW = 20; RESOURCE_POOL = 21; + TRANSFER = 23; } // Name of scheme entry (dir2 of /dir1/dir2) diff --git a/src/client/table/table.cpp b/src/client/table/table.cpp index 820e5ed59b..ae962207a4 100644 --- a/src/client/table/table.cpp +++ b/src/client/table/table.cpp @@ -2040,6 +2040,14 @@ const std::optional& TDataQuery::GetText() const { return Impl_->GetText(); } +std::map TDataQuery::GetParameterTypes() const { + std::map typesMap; + for (const auto& param : Impl_->ParameterTypes_) { + typesMap.emplace(param.first, TType(param.second)); + } + return typesMap; +} + TParamsBuilder TDataQuery::GetParamsBuilder() const { return TParamsBuilder(Impl_->ParameterTypes_); } From 172ee0ab7da7c58293e75004729b94f3df9a3754 Mon Sep 17 00:00:00 2001 From: Daniil Demin Date: Fri, 28 Mar 2025 18:27:22 +0000 Subject: [PATCH 06/13] kesus: support in recursive rmdir (#16129) --- include/ydb-cpp-sdk/client/coordination/coordination.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/ydb-cpp-sdk/client/coordination/coordination.h b/include/ydb-cpp-sdk/client/coordination/coordination.h index d1893ee6ff..4b46428ca9 100644 --- a/include/ydb-cpp-sdk/client/coordination/coordination.h +++ b/include/ydb-cpp-sdk/client/coordination/coordination.h @@ -198,7 +198,9 @@ struct TCreateNodeSettings : public TNodeSettings { TCreateNodeSettings(const Ydb::Coordination::Config& config); }; struct TAlterNodeSettings : public TNodeSettings { }; -struct TDropNodeSettings : public TOperationRequestSettings { }; +struct TDropNodeSettings : public TOperationRequestSettings { + using TOperationRequestSettings::TOperationRequestSettings; +}; struct TDescribeNodeSettings : public TOperationRequestSettings { }; //////////////////////////////////////////////////////////////////////////////// From c957c9335f3312b5eb7cc8d3c454032a9a310947 Mon Sep 17 00:00:00 2001 From: Daniil Cherednik Date: Fri, 28 Mar 2025 18:27:38 +0000 Subject: [PATCH 07/13] Allow to skip discovery routine in the C++ SDK for driver/client scope. (#16226) --- include/ydb-cpp-sdk/client/types/ydb.h | 5 +- .../ydb_internal/db_driver_state/state.cpp | 37 ++++++++------ .../grpc_connections/grpc_connections.h | 42 ++++++++++------ tests/unit/client/driver/driver_ut.cpp | 50 +++++++++++++++++++ 4 files changed, 102 insertions(+), 32 deletions(-) diff --git a/include/ydb-cpp-sdk/client/types/ydb.h b/include/ydb-cpp-sdk/client/types/ydb.h index 3957f1fedc..3ae912fadf 100644 --- a/include/ydb-cpp-sdk/client/types/ydb.h +++ b/include/ydb-cpp-sdk/client/types/ydb.h @@ -16,7 +16,10 @@ enum class EDiscoveryMode { //! we got endpoint list. The error will be returned if the endpoint list //! is empty and discovery failed //! This method is a bit more "user friendly" but can produce additional hidden latency - Async + Async, + //! Do not perform discovery. + //! This option disables database discovery and allow to use user provided endpoint for grpc connections + Off }; enum class EBalancingPolicy { diff --git a/src/client/impl/ydb_internal/db_driver_state/state.cpp b/src/client/impl/ydb_internal/db_driver_state/state.cpp index 76f94af60c..c71349bc00 100644 --- a/src/client/impl/ydb_internal/db_driver_state/state.cpp +++ b/src/client/impl/ydb_internal/db_driver_state/state.cpp @@ -205,27 +205,32 @@ TDbDriverStatePtr TDbDriverStateTracker::GetDriverState( ? credentialsProviderFactory->CreateProvider(strongState) : CreateInsecureCredentialsProviderFactory()->CreateProvider(strongState)); - DiscoveryClient_->AddPeriodicTask(CreatePeriodicDiscoveryTask(strongState), DISCOVERY_RECHECK_PERIOD); + if (discoveryMode != EDiscoveryMode::Off) { + DiscoveryClient_->AddPeriodicTask(CreatePeriodicDiscoveryTask(strongState), DISCOVERY_RECHECK_PERIOD); + } Y_ABORT_UNLESS(States_.emplace(key, strongState).second); break; } } - auto updateResult = strongState->EndpointPool.UpdateAsync(); - if (updateResult.second) { - auto cb = [strongState](const NThreading::TFuture&) { - strongState->SignalDiscoveryCompleted(); - }; - updateResult.first.Subscribe(cb); - } - if (strongState->DiscoveryMode == EDiscoveryMode::Sync) { - const auto& discoveryStatus = updateResult.first.GetValueSync().DiscoveryStatus; - // Almost always true, except the situation when the current thread was - // preempted just before UpdateAsync call and other one get - // state from cache and call UpdateAsync before us. - if (Y_LIKELY(updateResult.second)) { - std::unique_lock guard(strongState->LastDiscoveryStatusRWLock); - strongState->LastDiscoveryStatus = discoveryStatus; + if (strongState->DiscoveryMode != EDiscoveryMode::Off) { + auto updateResult = strongState->EndpointPool.UpdateAsync(); + if (updateResult.second) { + auto cb = [strongState](const NThreading::TFuture&) { + strongState->SignalDiscoveryCompleted(); + }; + updateResult.first.Subscribe(cb); + } + + if (strongState->DiscoveryMode == EDiscoveryMode::Sync) { + const auto& discoveryStatus = updateResult.first.GetValueSync().DiscoveryStatus; + // Almost always true, except the situation when the current thread was + // preempted just before UpdateAsync call and other one get + // state from cache and call UpdateAsync before us. + if (Y_LIKELY(updateResult.second)) { + std::unique_lock guard(strongState->LastDiscoveryStatusRWLock); + strongState->LastDiscoveryStatus = discoveryStatus; + } } } diff --git a/src/client/impl/ydb_internal/grpc_connections/grpc_connections.h b/src/client/impl/ydb_internal/grpc_connections/grpc_connections.h index 6d3012900b..db777210ca 100644 --- a/src/client/impl/ydb_internal/grpc_connections/grpc_connections.h +++ b/src/client/impl/ydb_internal/grpc_connections/grpc_connections.h @@ -98,20 +98,22 @@ class TGRpcConnectionsImpl clientConfig.MaxOutboundMessageSize = MaxOutboundMessageSize_; } - if (std::is_same() - || dbState->Database.empty() - || endpointPolicy == TRpcRequestSettings::TEndpointPolicy::UseDiscoveryEndpoint) - { - SetGrpcKeepAlive(clientConfig, GRPC_KEEP_ALIVE_TIMEOUT_FOR_DISCOVERY, GRpcKeepAlivePermitWithoutCalls_); - } else { - auto endpoint = dbState->EndpointPool.GetEndpoint(preferredEndpoint, endpointPolicy == TRpcRequestSettings::TEndpointPolicy::UsePreferredEndpointStrictly); - if (!endpoint) { - return {nullptr, TEndpointKey()}; - } - clientConfig.Locator = endpoint.Endpoint; - clientConfig.SslTargetNameOverride = endpoint.SslTargetNameOverride; - if (GRpcKeepAliveTimeout_) { - SetGrpcKeepAlive(clientConfig, GRpcKeepAliveTimeout_, GRpcKeepAlivePermitWithoutCalls_); + if (dbState->DiscoveryMode != EDiscoveryMode::Off) { + if (std::is_same() + || dbState->Database.empty() + || endpointPolicy == TRpcRequestSettings::TEndpointPolicy::UseDiscoveryEndpoint) + { + SetGrpcKeepAlive(clientConfig, GRPC_KEEP_ALIVE_TIMEOUT_FOR_DISCOVERY, GRpcKeepAlivePermitWithoutCalls_); + } else { + auto endpoint = dbState->EndpointPool.GetEndpoint(preferredEndpoint, endpointPolicy == TRpcRequestSettings::TEndpointPolicy::UsePreferredEndpointStrictly); + if (!endpoint) { + return {nullptr, TEndpointKey()}; + } + clientConfig.Locator = endpoint.Endpoint; + clientConfig.SslTargetNameOverride = endpoint.SslTargetNameOverride; + if (GRpcKeepAliveTimeout_) { + SetGrpcKeepAlive(clientConfig, GRpcKeepAliveTimeout_, GRpcKeepAlivePermitWithoutCalls_); + } } } @@ -609,7 +611,17 @@ class TGRpcConnectionsImpl TEndpointKey endpoint; std::tie(serviceConnection, endpoint) = GetServiceConnection(dbState, preferredEndpoint, endpointPolicy); if (!serviceConnection) { - if (dbState->DiscoveryMode == EDiscoveryMode::Sync) { + if (dbState->DiscoveryMode == EDiscoveryMode::Off) { + TStringStream errString; + errString << "No endpoint for database " << dbState->Database; + errString << ", cluster endpoint " << dbState->DiscoveryEndpoint; + dbState->StatCollector.IncReqFailNoEndpoint(); + callback( + TPlainStatus(EStatus::UNAVAILABLE, errString.Str()), + TConnection{nullptr}, + TEndpointKey{ }); + + } else if (dbState->DiscoveryMode == EDiscoveryMode::Sync) { TStringStream errString; errString << "Endpoint list is empty for database " << dbState->Database; errString << ", cluster endpoint " << dbState->DiscoveryEndpoint; diff --git a/tests/unit/client/driver/driver_ut.cpp b/tests/unit/client/driver/driver_ut.cpp index 46154caec7..925826cbe3 100644 --- a/tests/unit/client/driver/driver_ut.cpp +++ b/tests/unit/client/driver/driver_ut.cpp @@ -183,4 +183,54 @@ Y_UNIT_TEST_SUITE(CppGrpcClientSimpleTest) { auto session = sessionResult.GetSession(); UNIT_ASSERT_VALUES_EQUAL(session.GetId(), "my-session-id"); } + + Y_UNIT_TEST(WithoutDiscoveryDriverLevel) { + TPortManager pm; + + // Start our mock table service + TMockTableService tableService; + ui16 tablePort = pm.GetPort(); + auto tableServer = StartGrpcServer( + TStringBuilder() << "127.0.0.1:" << tablePort, + tableService); + + auto driver = TDriver( + TDriverConfig() + .SetEndpoint(TStringBuilder() << "localhost:" << tablePort) + .SetDiscoveryMode(EDiscoveryMode::Off) + .SetDatabase("/Root/My/DB")); + auto client = NTable::TTableClient(driver); + auto sessionFuture = client.CreateSession(); + + UNIT_ASSERT(sessionFuture.Wait(TDuration::Seconds(10))); + auto sessionResult = sessionFuture.ExtractValueSync(); + UNIT_ASSERT(sessionResult.IsSuccess()); + auto session = sessionResult.GetSession(); + UNIT_ASSERT_VALUES_EQUAL(session.GetId(), "my-session-id"); + } + + Y_UNIT_TEST(WithoutDiscoveryClientLevel) { + TPortManager pm; + + // Start our mock table service + TMockTableService tableService; + ui16 tablePort = pm.GetPort(); + auto tableServer = StartGrpcServer( + TStringBuilder() << "127.0.0.1:" << tablePort, + tableService); + + auto driver = TDriver( + TDriverConfig() + .SetEndpoint(TStringBuilder() << "localhost:" << tablePort) + .SetDatabase("/Root/My/DB")); + auto client = NTable::TTableClient(driver, TClientSettings().DiscoveryMode(EDiscoveryMode::Off)); + auto sessionFuture = client.CreateSession(); + + UNIT_ASSERT(sessionFuture.Wait(TDuration::Seconds(10))); + auto sessionResult = sessionFuture.ExtractValueSync(); + UNIT_ASSERT(sessionResult.IsSuccess()); + auto session = sessionResult.GetSession(); + UNIT_ASSERT_VALUES_EQUAL(session.GetId(), "my-session-id"); + } + } From 5cf89a2bac09fab69701b5404a3e0a098cd11bfe Mon Sep 17 00:00:00 2001 From: Vasily Gerasimov Date: Fri, 28 Mar 2025 18:28:00 +0000 Subject: [PATCH 08/13] Refactor ydb cli options (#15800) --- examples/secondary_index/secondary_index_list.cpp | 2 +- src/api/protos/draft/ydb_maintenance.proto | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/examples/secondary_index/secondary_index_list.cpp b/examples/secondary_index/secondary_index_list.cpp index 59e127d8ba..1946e67dcf 100644 --- a/examples/secondary_index/secondary_index_list.cpp +++ b/examples/secondary_index/secondary_index_list.cpp @@ -246,7 +246,7 @@ int RunListSeries(TDriver& driver, const std::string& prefix, int argc, char** a uint64_t lastSeriesId = -1; uint64_t lastViews = -1; - opts.AddLongOption("by-views", "Sort by views").NoArgument().SetFlag(&byViews); + opts.AddLongOption("by-views", "Sort by views").StoreTrue(&byViews); opts.AddLongOption("limit", "Maximum number of rows").Optional().RequiredArgument("NUM") .StoreResult(&limit); opts.AddLongOption("last-id", "Resume from this last series id").Optional().RequiredArgument("NUM") diff --git a/src/api/protos/draft/ydb_maintenance.proto b/src/api/protos/draft/ydb_maintenance.proto index 477d0c2127..39b7c67d32 100644 --- a/src/api/protos/draft/ydb_maintenance.proto +++ b/src/api/protos/draft/ydb_maintenance.proto @@ -96,9 +96,24 @@ message MaintenanceTaskOptions { // Used to describe the scope of a single action. message ActionScope { + message PDiskId { + uint32 node_id = 1; + uint32 pdisk_id = 2; + } + message PDiskLocation { + string host = 1 [(length).le = 255]; + string path = 2 [(length).le = 255]; + } + message PDisk { + oneof pdisk { + PDiskId pdisk_id = 1; + PDiskLocation pdisk_location = 2; + } + } oneof scope { uint32 node_id = 1; string host = 2 [(length).le = 255]; + PDisk pdisk = 3; } } From 47ababed49aba20eb920fce812e4f2991d4a823a Mon Sep 17 00:00:00 2001 From: Bulat Date: Fri, 28 Mar 2025 18:28:18 +0000 Subject: [PATCH 09/13] [SDK] Fixed use-after-move in topic write session (#16369) --- src/client/topic/impl/write_session_impl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/topic/impl/write_session_impl.cpp b/src/client/topic/impl/write_session_impl.cpp index ddfb6587ca..21ea692a4d 100644 --- a/src/client/topic/impl/write_session_impl.cpp +++ b/src/client/topic/impl/write_session_impl.cpp @@ -951,7 +951,7 @@ void TWriteSessionImpl::OnReadDone(NYdbGrpc::TGrpcStatus&& grpcStatus, size_t co TProcessSrvMessageResult processResult; bool needSetValue = false; if (!grpcStatus.Ok()) { - errorStatus = TPlainStatus(std::move(grpcStatus)); + errorStatus = TPlainStatus(grpcStatus); } bool doRead = false; { From 5430875df44fa9a019fa1a47370354c0875d4d61 Mon Sep 17 00:00:00 2001 From: Nikolay Shestakov Date: Fri, 28 Mar 2025 18:28:59 +0000 Subject: [PATCH 10/13] Added the ability to pause and resume transfers (#16339) --- include/ydb-cpp-sdk/client/draft/ydb_replication.h | 7 ++++++- src/api/protos/draft/ydb_replication.proto | 4 ++++ src/client/draft/ydb_replication.cpp | 8 ++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/include/ydb-cpp-sdk/client/draft/ydb_replication.h b/include/ydb-cpp-sdk/client/draft/ydb_replication.h index ba8a872bfb..09eb0725d8 100644 --- a/include/ydb-cpp-sdk/client/draft/ydb_replication.h +++ b/include/ydb-cpp-sdk/client/draft/ydb_replication.h @@ -100,6 +100,8 @@ class TRunningState { struct TDoneState {}; +struct TPausedState {}; + class TErrorState { class TImpl; @@ -131,6 +133,7 @@ class TReplicationDescription { Running, Error, Done, + Paused, }; explicit TReplicationDescription(const Ydb::Replication::DescribeReplicationResult& desc); @@ -145,6 +148,7 @@ class TReplicationDescription { const TRunningState& GetRunningState() const; const TErrorState& GetErrorState() const; const TDoneState& GetDoneState() const; + const TPausedState& GetPausedState() const; private: TConnectionParams ConnectionParams_; @@ -158,7 +162,8 @@ class TReplicationDescription { std::variant< TRunningState, TErrorState, - TDoneState + TDoneState, + TPausedState > State_; }; diff --git a/src/api/protos/draft/ydb_replication.proto b/src/api/protos/draft/ydb_replication.proto index 36ff7119a1..4ef82408e6 100644 --- a/src/api/protos/draft/ydb_replication.proto +++ b/src/api/protos/draft/ydb_replication.proto @@ -77,6 +77,9 @@ message DescribeReplicationResult { message DoneState { } + message PausedState { + } + // Description of scheme object. Ydb.Scheme.Entry self = 1; @@ -90,6 +93,7 @@ message DescribeReplicationResult { RunningState running = 4; ErrorState error = 5; DoneState done = 6; + PausedState paused = 9; } } diff --git a/src/client/draft/ydb_replication.cpp b/src/client/draft/ydb_replication.cpp index c6b2a61adf..d637cb3e7f 100644 --- a/src/client/draft/ydb_replication.cpp +++ b/src/client/draft/ydb_replication.cpp @@ -162,6 +162,10 @@ TReplicationDescription::TReplicationDescription(const Ydb::Replication::Describ State_ = TDoneState(); break; + case Ydb::Replication::DescribeReplicationResult::kPaused: + State_ = TPausedState(); + break; + default: break; } @@ -200,6 +204,10 @@ const TDoneState& TReplicationDescription::GetDoneState() const { return std::get(State_); } +const TPausedState& TReplicationDescription::GetPausedState() const { + return std::get(State_); +} + TDescribeReplicationResult::TDescribeReplicationResult(TStatus&& status, Ydb::Replication::DescribeReplicationResult&& desc) : NScheme::TDescribePathResult(std::move(status), desc.self()) , ReplicationDescription_(desc) From 2df27f37fe0949c95c177b0b6551e7d038d73517 Mon Sep 17 00:00:00 2001 From: yumkam Date: Fri, 28 Mar 2025 18:29:18 +0000 Subject: [PATCH 11/13] [ydb-sdk] add federated topic client GetAllClusters method (#16070) --- .../client/federated_topic/federated_topic.h | 28 +++++++++++++++ .../federated_topic/impl/federated_topic.cpp | 29 ++++++++++++++++ .../impl/federated_topic_impl.cpp | 34 +++++++++++++++++++ .../impl/federated_topic_impl.h | 2 ++ .../impl/federation_observer.cpp | 3 ++ 5 files changed, 96 insertions(+) diff --git a/include/ydb-cpp-sdk/client/federated_topic/federated_topic.h b/include/ydb-cpp-sdk/client/federated_topic/federated_topic.h index e1fff416ab..45e9809b63 100644 --- a/include/ydb-cpp-sdk/client/federated_topic/federated_topic.h +++ b/include/ydb-cpp-sdk/client/federated_topic/federated_topic.h @@ -15,6 +15,8 @@ using TDbInfo = Ydb::FederationDiscovery::DatabaseInfo; using TSessionClosedEvent = NTopic::TSessionClosedEvent; +using TAsyncDescribeTopicResult = NTopic::TAsyncDescribeTopicResult; + //! Federated partition session. struct TFederatedPartitionSession : public TThrRefBase, public TPrintable { using TPtr = TIntrusivePtr; @@ -516,6 +518,32 @@ class TFederatedTopicClient { // std::shared_ptr CreateSimpleBlockingWriteSession(const TFederatedWriteSessionSettings& settings); std::shared_ptr CreateWriteSession(const TFederatedWriteSessionSettings& settings); + struct TClusterInfo { + enum class EStatus : int { + STATUS_UNSPECIFIED, + AVAILABLE, + READ_ONLY, + UNAVAILABLE, + }; + std::string Name; + std::string Endpoint; + std::string Path; + EStatus Status; + // TODO: Id, Weight, ...? + //! Replaces Endpoint and Database for federated clusters + void AdjustTopicClientSettings(NTopic::TTopicClientSettings& settings) const; + //! Prepend Database for federated clusters + void AdjustTopicPath(std::string& path) const; + //! Usable for at least read operations + bool IsAvailableForRead() const; + bool IsAvailableForWrite() const; + }; + + //! Discover all clusters for federated topic. + // Will return single cluster with empty name for non-federated clusters. + // May return empty list if FederatedTopicClient was destroyed when future fired. + NThreading::TFuture> GetAllClusterInfo(); + protected: void OverrideCodec(NTopic::ECodec codecId, std::unique_ptr&& codecImpl); diff --git a/src/client/federated_topic/impl/federated_topic.cpp b/src/client/federated_topic/impl/federated_topic.cpp index ca1a1caa3f..5b0f7f2b19 100644 --- a/src/client/federated_topic/impl/federated_topic.cpp +++ b/src/client/federated_topic/impl/federated_topic.cpp @@ -86,4 +86,33 @@ void TFederatedTopicClient::OverrideCodec(NTopic::ECodec codecId, std::unique_pt return Impl_->OverrideCodec(codecId, std::move(codecImpl)); } +NThreading::TFuture> TFederatedTopicClient::GetAllClusterInfo() { + return Impl_->GetAllClusterInfo(); +} + +void TFederatedTopicClient::TClusterInfo::AdjustTopicClientSettings(NTopic::TTopicClientSettings& settings) const { + if (Name.empty()) { + return; + } + settings.DiscoveryEndpoint(Endpoint); + settings.Database(Path); +} + +void TFederatedTopicClient::TClusterInfo::AdjustTopicPath(std::string& path) const { + if (Name.empty()) { + return; + } + if (path.empty() || path[0] != '/') { + path = Path + '/' + path; + } +} + +bool TFederatedTopicClient::TClusterInfo::IsAvailableForRead() const { + return Status == TClusterInfo::EStatus::AVAILABLE || Status == TClusterInfo::EStatus::READ_ONLY; +} + +bool TFederatedTopicClient::TClusterInfo::IsAvailableForWrite() const { + return Status == TClusterInfo::EStatus::AVAILABLE; +} + } // namespace NYdb::NFederatedTopic diff --git a/src/client/federated_topic/impl/federated_topic_impl.cpp b/src/client/federated_topic/impl/federated_topic_impl.cpp index 4a1384800e..53e4f18204 100644 --- a/src/client/federated_topic/impl/federated_topic_impl.cpp +++ b/src/client/federated_topic/impl/federated_topic_impl.cpp @@ -49,6 +49,40 @@ void TFederatedTopicClient::TImpl::InitObserver() { } } +NThreading::TFuture> TFederatedTopicClient::TImpl::GetAllClusterInfo() { + InitObserver(); + return Observer->WaitForFirstState().Apply( + [weakObserver = std::weak_ptr(Observer)] (const auto& ) { + std::vector result; + auto observer = weakObserver.lock(); + if (!observer) { + return result; + } + auto state = observer->GetState(); + result.reserve(state->DbInfos.size()); + for (const auto& db: state->DbInfos) { + auto& dbinfo = result.emplace_back(); + switch (db->status()) { +#define TRANSLATE_STATUS(NAME) \ + case TDbInfo::Status::DatabaseInfo_Status_##NAME: \ + dbinfo.Status = TClusterInfo::EStatus::NAME; \ + break + TRANSLATE_STATUS(STATUS_UNSPECIFIED); + TRANSLATE_STATUS(AVAILABLE); + TRANSLATE_STATUS(READ_ONLY); + TRANSLATE_STATUS(UNAVAILABLE); + default: + Y_ENSURE(false /* impossible status */); + } +#undef TRANSLATE_STATUS + dbinfo.Name = db->name(); + dbinfo.Endpoint = db->endpoint(); + dbinfo.Path = db->path(); + } + return result; + }); +} + auto TFederatedTopicClient::TImpl::GetSubsessionHandlersExecutor() -> NTopic::IExecutor::TPtr { with_lock (Lock) { if (!SubsessionHandlersExecutor) { diff --git a/src/client/federated_topic/impl/federated_topic_impl.h b/src/client/federated_topic/impl/federated_topic_impl.h index 164dd82cd6..7638904dab 100644 --- a/src/client/federated_topic/impl/federated_topic_impl.h +++ b/src/client/federated_topic/impl/federated_topic_impl.h @@ -65,6 +65,8 @@ class TFederatedTopicClient::TImpl { std::shared_ptr CreateSimpleBlockingWriteSession(const TFederatedWriteSessionSettings& settings); std::shared_ptr CreateWriteSession(const TFederatedWriteSessionSettings& settings); + NThreading::TFuture> GetAllClusterInfo(); + std::shared_ptr GetObserver() { std::lock_guard guard(Lock); return Observer; diff --git a/src/client/federated_topic/impl/federation_observer.cpp b/src/client/federated_topic/impl/federation_observer.cpp index 467dabfbbe..9d40845c62 100644 --- a/src/client/federated_topic/impl/federation_observer.cpp +++ b/src/client/federated_topic/impl/federation_observer.cpp @@ -197,6 +197,9 @@ IOutputStream& operator<<(IOutputStream& out, TFederatedDbState const& state) { } out << " ]"; } + if (!state.ControlPlaneEndpoint.empty()) { + out << " ControlPlaneEndpoint: " << state.ControlPlaneEndpoint; + } return out << " }"; } From 1e69303fe132cb97f0b89ead7b5e1383d306069d Mon Sep 17 00:00:00 2001 From: Mikhnenko Sasha <78651190+4JustMe4@users.noreply.github.com> Date: Fri, 28 Mar 2025 18:29:33 +0000 Subject: [PATCH 12/13] Use `uncaught_exceptions` instead of removed in c++20 `uncaught_exception` (#16380) --- src/client/persqueue_public/ut/read_session_ut.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/persqueue_public/ut/read_session_ut.cpp b/src/client/persqueue_public/ut/read_session_ut.cpp index 8ab0db9712..895a2aa96f 100644 --- a/src/client/persqueue_public/ut/read_session_ut.cpp +++ b/src/client/persqueue_public/ut/read_session_ut.cpp @@ -595,7 +595,7 @@ TReadSessionImplTestSetup::TReadSessionImplTestSetup() { } TReadSessionImplTestSetup::~TReadSessionImplTestSetup() noexcept(false) { - if (!std::uncaught_exception()) { // Exiting from test successfully. Check additional expectations. + if (!std::uncaught_exceptions()) { // Exiting from test successfully. Check additional expectations. MockProcessorFactory->Wait(); MockProcessor->Wait(); From b6cd5ca3244dd22af9fecb4d7a81b9981999edfb Mon Sep 17 00:00:00 2001 From: Bulat Gayazov Date: Mon, 31 Mar 2025 13:39:29 +0000 Subject: [PATCH 13/13] [C++ SDK] Refactor version increment (#16426) --- CMakeLists.txt | 5 ++++- include/ydb-cpp-sdk/type_switcher.h | 2 +- src/client/resources/CMakeLists.txt | 2 -- src/client/resources/ydb_ca.cpp | 4 +++- src/client/resources/ydb_resources.cpp | 4 +++- src/client/resources/ydb_sdk_version.txt | 1 - src/version.h | 8 ++++++++ 7 files changed, 19 insertions(+), 7 deletions(-) delete mode 100644 src/client/resources/ydb_sdk_version.txt create mode 100644 src/version.h diff --git a/CMakeLists.txt b/CMakeLists.txt index d0b2557078..a1e8a38f64 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,10 @@ set(YDB_SDK_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(YDB_SDK_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) set(YDB-CPP-SDK_AVAILABLE_COMPONENTS "" CACHE INTERNAL "") set(YDB-CPP-SDK_COMPONENT_TARGETS "" CACHE INTERNAL "") -file(READ "src/client/resources/ydb_sdk_version.txt" YDB_SDK_VERSION) +file(READ "src/version.h" YDB_SDK_VERSION_FILE_RAW) +string(REGEX MATCH "YDB_SDK_VERSION = \"([0-9]+\\.[0-9]+\\.[0-9]+)\"" _ ${YDB_SDK_VERSION_FILE_RAW}) +set(YDB_SDK_VERSION ${CMAKE_MATCH_1}) +message(STATUS "YDB ะก++ SDK version: ${YDB_SDK_VERSION}") #[=============================================================================[ NOTE: if `ccache` is used with the environment variable `CCACHE_BASEDIR`, diff --git a/include/ydb-cpp-sdk/type_switcher.h b/include/ydb-cpp-sdk/type_switcher.h index d0efd61d7d..f7c189adc5 100644 --- a/include/ydb-cpp-sdk/type_switcher.h +++ b/include/ydb-cpp-sdk/type_switcher.h @@ -3,7 +3,7 @@ #include namespace NYdb { -inline namespace Dev { +inline namespace V3 { using TStringType = std::string; diff --git a/src/client/resources/CMakeLists.txt b/src/client/resources/CMakeLists.txt index 3074324f62..24a9f19ac5 100644 --- a/src/client/resources/CMakeLists.txt +++ b/src/client/resources/CMakeLists.txt @@ -19,10 +19,8 @@ target_sources(client-resources.global PRIVATE resources(client-resources.global ${YDB_SDK_BINARY_DIR}/src/client/resources/6ed212bf45019efe2a5e72b6d5ed50fb.cpp INPUTS - ${YDB_SDK_SOURCE_DIR}/src/client/resources/ydb_sdk_version.txt ${YDB_SDK_SOURCE_DIR}/src/client/resources/ydb_root_ca.pem KEYS - ydb_sdk_version_v3.txt ydb_root_ca_v3.pem ) diff --git a/src/client/resources/ydb_ca.cpp b/src/client/resources/ydb_ca.cpp index 8da95f1dbe..916ab09a24 100644 --- a/src/client/resources/ydb_ca.cpp +++ b/src/client/resources/ydb_ca.cpp @@ -2,10 +2,12 @@ #include +#include + namespace NYdb::inline V3 { std::string GetRootCertificate() { - return NResource::Find("ydb_root_ca_dev.pem"); + return NResource::Find(YDB_CERTIFICATE_FILE_KEY); } } // namespace NYdb diff --git a/src/client/resources/ydb_resources.cpp b/src/client/resources/ydb_resources.cpp index 1b3edb7f5b..ac91564718 100644 --- a/src/client/resources/ydb_resources.cpp +++ b/src/client/resources/ydb_resources.cpp @@ -2,6 +2,8 @@ #include +#include + namespace NYdb::inline V3 { const char* YDB_AUTH_TICKET_HEADER = "x-ydb-auth-ticket"; @@ -29,7 +31,7 @@ const char* YDB_CLIENT_CAPABILITY_SESSION_BALANCER = "session-balancer"; std::string GetSdkSemver() { - return NResource::Find("ydb_sdk_version_dev.txt"); + return YDB_SDK_VERSION; } } // namespace NYdb diff --git a/src/client/resources/ydb_sdk_version.txt b/src/client/resources/ydb_sdk_version.txt deleted file mode 100644 index acf9bf09db..0000000000 --- a/src/client/resources/ydb_sdk_version.txt +++ /dev/null @@ -1 +0,0 @@ -3.2.2 \ No newline at end of file diff --git a/src/version.h b/src/version.h new file mode 100644 index 0000000000..dc5f199bd1 --- /dev/null +++ b/src/version.h @@ -0,0 +1,8 @@ +#pragma once + +namespace NYdb { + +inline const char* YDB_SDK_VERSION = "3.3.0"; +inline const char* YDB_CERTIFICATE_FILE_KEY = "ydb_root_ca_v3.pem"; + +} // namespace NYdb