diff options
author | kmokrov <kmokrov@yandex-team.com> | 2023-11-22 10:28:22 +0300 |
---|---|---|
committer | kmokrov <kmokrov@yandex-team.com> | 2023-11-22 11:41:40 +0300 |
commit | 4fbe60cb421e9b6db948035286ce602e1c2627c8 (patch) | |
tree | ad2bcc9781d035380a78150a4f5be4265bff4674 | |
parent | 249ee0f96c44611750d44f049163c517cc87f323 (diff) | |
download | ydb-4fbe60cb421e9b6db948035286ce602e1c2627c8.tar.gz |
YTORM-843: Move checkUTF8 protobuf-interop option to global config
move option to config
-rw-r--r-- | yt/yt/core/CMakeLists.darwin-arm64.txt | 1 | ||||
-rw-r--r-- | yt/yt/core/CMakeLists.darwin-x86_64.txt | 1 | ||||
-rw-r--r-- | yt/yt/core/CMakeLists.linux-aarch64.txt | 1 | ||||
-rw-r--r-- | yt/yt/core/CMakeLists.linux-x86_64.txt | 1 | ||||
-rw-r--r-- | yt/yt/core/CMakeLists.windows-x86_64.txt | 1 | ||||
-rw-r--r-- | yt/yt/core/ya.make | 3 | ||||
-rw-r--r-- | yt/yt/core/yson/config.cpp | 15 | ||||
-rw-r--r-- | yt/yt/core/yson/config.h | 32 | ||||
-rw-r--r-- | yt/yt/core/yson/protobuf_interop.cpp | 47 | ||||
-rw-r--r-- | yt/yt/core/yson/protobuf_interop.h | 6 | ||||
-rw-r--r-- | yt/yt/core/yson/protobuf_interop_options.h | 12 | ||||
-rw-r--r-- | yt/yt/core/yson/public.h | 10 | ||||
-rw-r--r-- | yt/yt/core/yson/unittests/protobuf_yson_ut.cpp | 20 | ||||
-rw-r--r-- | yt/yt/library/program/config.cpp | 2 | ||||
-rw-r--r-- | yt/yt/library/program/config.h | 3 | ||||
-rw-r--r-- | yt/yt/library/program/helpers.cpp | 6 |
16 files changed, 130 insertions, 31 deletions
diff --git a/yt/yt/core/CMakeLists.darwin-arm64.txt b/yt/yt/core/CMakeLists.darwin-arm64.txt index 24ff6ecc0d..39189652b2 100644 --- a/yt/yt/core/CMakeLists.darwin-arm64.txt +++ b/yt/yt/core/CMakeLists.darwin-arm64.txt @@ -253,6 +253,7 @@ target_sources(yt-yt-core PRIVATE ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/async_consumer.cpp ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/async_writer.cpp ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/attribute_consumer.cpp + ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/config.cpp ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/consumer.cpp ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/forwarding_consumer.cpp ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/lexer.cpp diff --git a/yt/yt/core/CMakeLists.darwin-x86_64.txt b/yt/yt/core/CMakeLists.darwin-x86_64.txt index 5b4d4b633f..c683eefee9 100644 --- a/yt/yt/core/CMakeLists.darwin-x86_64.txt +++ b/yt/yt/core/CMakeLists.darwin-x86_64.txt @@ -254,6 +254,7 @@ target_sources(yt-yt-core PRIVATE ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/async_consumer.cpp ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/async_writer.cpp ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/attribute_consumer.cpp + ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/config.cpp ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/consumer.cpp ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/forwarding_consumer.cpp ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/lexer.cpp diff --git a/yt/yt/core/CMakeLists.linux-aarch64.txt b/yt/yt/core/CMakeLists.linux-aarch64.txt index 640e862300..fc9f31ca0a 100644 --- a/yt/yt/core/CMakeLists.linux-aarch64.txt +++ b/yt/yt/core/CMakeLists.linux-aarch64.txt @@ -254,6 +254,7 @@ target_sources(yt-yt-core PRIVATE ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/async_consumer.cpp ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/async_writer.cpp ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/attribute_consumer.cpp + ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/config.cpp ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/consumer.cpp ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/forwarding_consumer.cpp ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/lexer.cpp diff --git a/yt/yt/core/CMakeLists.linux-x86_64.txt b/yt/yt/core/CMakeLists.linux-x86_64.txt index ab2ddf3548..104037bd3c 100644 --- a/yt/yt/core/CMakeLists.linux-x86_64.txt +++ b/yt/yt/core/CMakeLists.linux-x86_64.txt @@ -255,6 +255,7 @@ target_sources(yt-yt-core PRIVATE ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/async_consumer.cpp ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/async_writer.cpp ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/attribute_consumer.cpp + ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/config.cpp ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/consumer.cpp ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/forwarding_consumer.cpp ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/lexer.cpp diff --git a/yt/yt/core/CMakeLists.windows-x86_64.txt b/yt/yt/core/CMakeLists.windows-x86_64.txt index 741f6b7a8b..2e3be60648 100644 --- a/yt/yt/core/CMakeLists.windows-x86_64.txt +++ b/yt/yt/core/CMakeLists.windows-x86_64.txt @@ -253,6 +253,7 @@ target_sources(yt-yt-core PRIVATE ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/async_consumer.cpp ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/async_writer.cpp ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/attribute_consumer.cpp + ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/config.cpp ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/consumer.cpp ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/forwarding_consumer.cpp ${CMAKE_SOURCE_DIR}/yt/yt/core/yson/lexer.cpp diff --git a/yt/yt/core/ya.make b/yt/yt/core/ya.make index 043d3a1dd9..d114db5cf8 100644 --- a/yt/yt/core/ya.make +++ b/yt/yt/core/ya.make @@ -228,6 +228,7 @@ SRCS( yson/async_consumer.cpp yson/async_writer.cpp yson/attribute_consumer.cpp + yson/config.cpp yson/consumer.cpp yson/forwarding_consumer.cpp yson/lexer.cpp @@ -324,7 +325,7 @@ PEERDIR( library/cpp/ytalloc/api yt/yt/build - + yt/yt/core/misc/isa_crc64 yt/yt_proto/yt/core diff --git a/yt/yt/core/yson/config.cpp b/yt/yt/core/yson/config.cpp new file mode 100644 index 0000000000..8ced712d57 --- /dev/null +++ b/yt/yt/core/yson/config.cpp @@ -0,0 +1,15 @@ +#include "config.h" + +namespace NYT::NYson { + +//////////////////////////////////////////////////////////////////////////////// + +void TProtobufInteropDynamicConfig::Register(TRegistrar registrar) +{ + registrar.Parameter("utf8_check", &TThis::Utf8Check) + .Default(EUtf8Check::Disable); +} + +//////////////////////////////////////////////////////////////////////////////// + +} // NYT::NYson diff --git a/yt/yt/core/yson/config.h b/yt/yt/core/yson/config.h new file mode 100644 index 0000000000..f4d987b2e9 --- /dev/null +++ b/yt/yt/core/yson/config.h @@ -0,0 +1,32 @@ +#pragma once + +#include "public.h" + +#include <yt/yt/core/ytree/yson_struct.h> + +#include <library/cpp/yt/memory/public.h> + +#include <library/cpp/yt/misc/enum.h> + +namespace NYT::NYson { + +//////////////////////////////////////////////////////////////////////////////// + +// TODO(kmokrov): Drop after YTORM-843 +class TProtobufInteropDynamicConfig + : public NYTree::TYsonStruct +{ +public: + // Check if string field contain actual UTF-8 string. + EUtf8Check Utf8Check; + + REGISTER_YSON_STRUCT(TProtobufInteropDynamicConfig); + + static void Register(TRegistrar registrar); +}; + +DEFINE_REFCOUNTED_TYPE(TProtobufInteropDynamicConfig) + +//////////////////////////////////////////////////////////////////////////////// + +} // NYT::NYson diff --git a/yt/yt/core/yson/protobuf_interop.cpp b/yt/yt/core/yson/protobuf_interop.cpp index 5941904abf..79772200b5 100644 --- a/yt/yt/core/yson/protobuf_interop.cpp +++ b/yt/yt/core/yson/protobuf_interop.cpp @@ -1,5 +1,6 @@ #include "protobuf_interop.h" +#include "config.h" #include "consumer.h" #include "forwarding_consumer.h" #include "null_consumer.h" @@ -26,6 +27,9 @@ #include <yt/yt/core/concurrency/thread_affinity.h> +#include <library/cpp/yt/memory/atomic_intrusive_ptr.h> +#include <library/cpp/yt/memory/leaky_singleton.h> + #include <library/cpp/yt/misc/cast.h> #include <library/cpp/yt/string/string.h> @@ -149,10 +153,36 @@ TString DeriveYsonName(const TString& protobufName, const google::protobuf::File } } +//////////////////////////////////////////////////////////////////////////////// + +struct TProtobufInteropConfigSingleton +{ + TAtomicIntrusivePtr<TProtobufInteropDynamicConfig> Config{New<TProtobufInteropDynamicConfig>()}; +}; + +TProtobufInteropConfigSingleton* GlobalProtobufInteropConfig() +{ + return LeakySingleton<TProtobufInteropConfigSingleton>(); +} + +TProtobufInteropDynamicConfigPtr GetProtobufInteropConfig() +{ + return GlobalProtobufInteropConfig()->Config.Acquire(); +} + +//////////////////////////////////////////////////////////////////////////////// + } // namespace //////////////////////////////////////////////////////////////////////////////// +void SetProtobufInteropConfig(TProtobufInteropDynamicConfigPtr config) +{ + GlobalProtobufInteropConfig()->Config.Store(std::move(config)); +} + +//////////////////////////////////////////////////////////////////////////////// + class TProtobufTypeRegistry { public: @@ -859,20 +889,21 @@ protected: } } - void ValidateString(TStringBuf data, EUtf8Check checkOption, TString fieldFullName) + void ValidateString(TStringBuf data, TString fieldFullName) { - if (checkOption == EUtf8Check::None || IsUtf(data)) { + auto config = GetProtobufInteropConfig(); + if (config->Utf8Check == EUtf8Check::Disable || IsUtf(data)) { return; } - switch (checkOption) { - case EUtf8Check::None: + switch (config->Utf8Check) { + case EUtf8Check::Disable: break; - case EUtf8Check::Log: + case EUtf8Check::LogOnFail: YT_LOG_WARNING("Field %v accepts only valid UTF-8 sequence, but got (%Qv)", YPathStack_.GetHumanReadablePath(), data); break; - case EUtf8Check::Throw: + case EUtf8Check::ThrowOnFail: THROW_ERROR_EXCEPTION("Field %v accepts only valid UTF-8 sequence, but got (%Qv)", YPathStack_.GetHumanReadablePath(), data) @@ -986,7 +1017,7 @@ private: const auto* field = FieldStack_.back().Field; switch (field->GetType()) { case FieldDescriptor::TYPE_STRING: - ValidateString(value, Options_.CheckUtf8, field->GetFullName()); + ValidateString(value, field->GetFullName()); case FieldDescriptor::TYPE_BYTES: BodyCodedStream_.WriteVarint64(value.length()); BodyCodedStream_.WriteRaw(value.begin(), static_cast<int>(value.length())); @@ -2508,7 +2539,7 @@ private: } TStringBuf data(PooledString_.data(), length); if (field->GetType() == FieldDescriptor::TYPE_STRING) { - ValidateString(data, Options_.CheckUtf8, field->GetFullName()); + ValidateString(data, field->GetFullName()); } ParseScalar([&] { if (field->GetBytesFieldConverter()) { diff --git a/yt/yt/core/yson/protobuf_interop.h b/yt/yt/core/yson/protobuf_interop.h index 8532c5c36e..efb2d0321f 100644 --- a/yt/yt/core/yson/protobuf_interop.h +++ b/yt/yt/core/yson/protobuf_interop.h @@ -1,5 +1,7 @@ #pragma once +#include "public.h" + #include "protobuf_interop_options.h" #include <yt/yt/core/ypath/public.h> @@ -273,6 +275,10 @@ TString YsonStringToProto( //////////////////////////////////////////////////////////////////////////////// +void SetProtobufInteropConfig(TProtobufInteropDynamicConfigPtr config); + +//////////////////////////////////////////////////////////////////////////////// + } // namespace NYT::NYson #define PROTOBUF_INTEROP_INL_H_ diff --git a/yt/yt/core/yson/protobuf_interop_options.h b/yt/yt/core/yson/protobuf_interop_options.h index 9df170c9c1..fbf9833e79 100644 --- a/yt/yt/core/yson/protobuf_interop_options.h +++ b/yt/yt/core/yson/protobuf_interop_options.h @@ -16,12 +16,6 @@ struct TResolveProtobufElementByYPathOptions bool AllowUnknownYsonFields = false; }; -DEFINE_ENUM(EUtf8Check, - (None) - (Log) - (Throw) -); - struct TProtobufWriterOptions { //! Keep: all unknown fields found during YSON parsing @@ -43,9 +37,6 @@ struct TProtobufWriterOptions //! silently skipped; otherwise an exception is thrown. bool SkipRequiredFields = false; - // Check if |string| fields contain actual UTF-8 strings. - EUtf8Check CheckUtf8 = EUtf8Check::None; - //! Convert yson keys from snake case to camel case. bool ConvertSnakeToCamelCase = false; }; @@ -59,9 +50,6 @@ struct TProtobufParserOptions //! If |true| then required fields not found in protobuf metadata are //! silently skipped; otherwise an exception is thrown. bool SkipRequiredFields = false; - - // Check if |string| fields contain actual UTF-8 strings. - EUtf8Check CheckUtf8 = EUtf8Check::None; }; //////////////////////////////////////////////////////////////////////////////// diff --git a/yt/yt/core/yson/public.h b/yt/yt/core/yson/public.h index 56d496fbee..d5fb112202 100644 --- a/yt/yt/core/yson/public.h +++ b/yt/yt/core/yson/public.h @@ -67,4 +67,14 @@ constexpr int DefaultYsonParserNestingLevelLimit = NewNestingLevelLimit; //////////////////////////////////////////////////////////////////////////////// +DEFINE_ENUM(EUtf8Check, + (Disable) + (LogOnFail) + (ThrowOnFail) +); + +DECLARE_REFCOUNTED_CLASS(TProtobufInteropDynamicConfig); + +//////////////////////////////////////////////////////////////////////////////// + } // namespace NYT::NYson diff --git a/yt/yt/core/yson/unittests/protobuf_yson_ut.cpp b/yt/yt/core/yson/unittests/protobuf_yson_ut.cpp index a15c3cd8a9..a8fc7aeef6 100644 --- a/yt/yt/core/yson/unittests/protobuf_yson_ut.cpp +++ b/yt/yt/core/yson/unittests/protobuf_yson_ut.cpp @@ -4,6 +4,7 @@ #include <yt/yt/core/yson/unittests/proto/protobuf_yson_casing_ut.pb.h> #include <yt/yt/core/yson/unittests/proto/protobuf_yson_casing_ext_ut.pb.h> +#include <yt/yt/core/yson/config.h> #include <yt/yt/core/yson/protobuf_interop.h> #include <yt/yt/core/yson/null_consumer.h> #include <yt/yt/core/yson/string_merger.h> @@ -1018,20 +1019,20 @@ TEST(TYsonToProtobufTest, Entities) TEST(TYsonToProtobufTest, ValidUtf8StringCheck) { - for (auto option: {EUtf8Check::None, EUtf8Check::Log, EUtf8Check::Throw}) { - TProtobufWriterOptions options{ - .CheckUtf8 = option, - }; + for (auto option: {EUtf8Check::Disable, EUtf8Check::LogOnFail, EUtf8Check::ThrowOnFail}) { + auto config = New<TProtobufInteropDynamicConfig>(); + config->Utf8Check = option; + SetProtobufInteropConfig(config); TString invalidUtf8 = "\xc3\x28"; auto check = [&] { - TEST_PROLOGUE_WITH_OPTIONS(TMessage, options) + TEST_PROLOGUE_WITH_OPTIONS(TMessage, {}) .BeginMap() .Item("string_field").Value(invalidUtf8) .EndMap(); }; - if (option == EUtf8Check::Throw) { + if (option == EUtf8Check::ThrowOnFail) { EXPECT_THROW_WITH_SUBSTRING(check(), "valid UTF-8"); } else { EXPECT_NO_THROW(check()); @@ -1042,12 +1043,11 @@ TEST(TYsonToProtobufTest, ValidUtf8StringCheck) TString newYsonString; TStringOutput newYsonOutputStream(newYsonString); TYsonWriter ysonWriter(&newYsonOutputStream, EYsonFormat::Pretty); - if (option == EUtf8Check::Throw) { + if (option == EUtf8Check::ThrowOnFail) { EXPECT_THROW_WITH_SUBSTRING( - WriteProtobufMessage(&ysonWriter, message, TProtobufParserOptions{.CheckUtf8 = option}), - "valid UTF-8"); + WriteProtobufMessage(&ysonWriter, message), "valid UTF-8"); } else { - EXPECT_NO_THROW(WriteProtobufMessage(&ysonWriter, message, TProtobufParserOptions{.CheckUtf8 = option})); + EXPECT_NO_THROW(WriteProtobufMessage(&ysonWriter, message)); } } } diff --git a/yt/yt/library/program/config.cpp b/yt/yt/library/program/config.cpp index ccc7bb1f2f..288a90a3b1 100644 --- a/yt/yt/library/program/config.cpp +++ b/yt/yt/library/program/config.cpp @@ -135,6 +135,8 @@ void TSingletonsDynamicConfig::Register(TRegistrar registrar) .DefaultNew(); registrar.Parameter("tcmalloc", &TThis::TCMalloc) .Optional(); + registrar.Parameter("protobuf_interop", &TThis::ProtobufInterop) + .DefaultNew(); } //////////////////////////////////////////////////////////////////////////////// diff --git a/yt/yt/library/program/config.h b/yt/yt/library/program/config.h index 88f649dd8e..b840950418 100644 --- a/yt/yt/library/program/config.h +++ b/yt/yt/library/program/config.h @@ -20,6 +20,8 @@ #include <yt/yt/core/service_discovery/yp/config.h> +#include <yt/yt/core/yson/config.h> + #include <yt/yt/library/profiling/solomon/exporter.h> #include <yt/yt/library/tracing/jaeger/tracer.h> @@ -171,6 +173,7 @@ public: NTracing::TJaegerTracerDynamicConfigPtr Jaeger; TRpcConfigPtr Rpc; TTCMallocConfigPtr TCMalloc; + NYson::TProtobufInteropDynamicConfigPtr ProtobufInterop; REGISTER_YSON_STRUCT(TSingletonsDynamicConfig); diff --git a/yt/yt/library/program/helpers.cpp b/yt/yt/library/program/helpers.cpp index fc4a84d828..dc06c9b044 100644 --- a/yt/yt/library/program/helpers.cpp +++ b/yt/yt/library/program/helpers.cpp @@ -25,6 +25,8 @@ #include <yt/yt/core/net/address.h> +#include <yt/yt/core/yson/protobuf_interop.h> + #include <yt/yt/core/rpc/dispatcher.h> #include <yt/yt/core/rpc/grpc/dispatcher.h> @@ -271,6 +273,10 @@ void ReconfigureSingletonsImpl(const TStaticConfig& config, const TDynamicConfig } else if (config->TCMalloc) { ConfigureTCMalloc(config->TCMalloc); } + + if (dynamicConfig->ProtobufInterop) { + NYson::SetProtobufInteropConfig(dynamicConfig->ProtobufInterop); + } } void ReconfigureSingletons(const TSingletonsConfigPtr& config, const TSingletonsDynamicConfigPtr& dynamicConfig) |