diff --git a/ydb/core/cms/console/configs_dispatcher.cpp b/ydb/core/cms/console/configs_dispatcher.cpp index c28255157fc4..10887d187ee4 100644 --- a/ydb/core/cms/console/configs_dispatcher.cpp +++ b/ydb/core/cms/console/configs_dispatcher.cpp @@ -186,8 +186,44 @@ class TConfigsDispatcher : public TActorBootstrapped { void Handle(TEvConsole::TEvGetNodeLabelsRequest::TPtr &ev); void Handle(TEvConsole::TEvFetchStartupConfigRequest::TPtr &ev); void Handle(TEvConsole::TEvGetNodeConfigurationVersionRequest::TPtr &ev); + void Handle(TEvConfigsDispatcher::TEvGetStateRequest::TPtr &ev); + void Handle(TEvConfigsDispatcher::TEvGetStorageYamlRequest::TPtr &ev); void ReplyMonJson(TActorId mailbox); + + EConfigSource DetermineConfigSource() const { + if (auto it = Labels.find("config_source"); it != Labels.end()) { + if (it->second == "seed_nodes") { + return EConfigSource::SeedNodes; + } + } + return EConfigSource::DynamicConfig; + } + + TConfigsDispatcherState GetState() const { + TConfigsDispatcherState state; + + auto configSource = DetermineConfigSource(); + state.ConfigSource = configSource; + + if (auto it = Labels.find("config_source"); it != Labels.end()) { + state.ConfigSourceLabel = it->second; + } + + if (auto it = Labels.find("configuration_version"); it != Labels.end()) { + state.ConfigurationVersion = it->second; + } + + state.HasStorageYaml = !StartupStorageYaml.empty(); + state.StorageYamlSize = StartupStorageYaml.size(); + state.YamlConfigEnabled = YamlConfigEnabled; + state.SubscriptionsCount = SubscriptionsByKinds.size(); + state.LastReplayUsedSeedNodesPath = LastReplayUsedSeedNodesPath; + state.LastReplayUsedDynamicConfigPath = LastReplayUsedDynamicConfigPath; + state.Labels = Labels; + + return state; + } STATEFN(StateInit) { @@ -203,6 +239,8 @@ class TConfigsDispatcher : public TActorBootstrapped { hFuncTraced(TEvConfigsDispatcher::TEvGetConfigRequest, Handle); hFuncTraced(TEvConfigsDispatcher::TEvSetConfigSubscriptionRequest, Handle); hFuncTraced(TEvConfigsDispatcher::TEvRemoveConfigSubscriptionRequest, Handle); + hFuncTraced(TEvConfigsDispatcher::TEvGetStateRequest, Handle); + hFuncTraced(TEvConfigsDispatcher::TEvGetStorageYamlRequest, Handle); // Resolve hFunc(TEvConsole::TEvGetNodeLabelsRequest, Handle); hFunc(TEvConsole::TEvFetchStartupConfigRequest, Handle); @@ -228,6 +266,8 @@ class TConfigsDispatcher : public TActorBootstrapped { hFuncTraced(TEvConfigsDispatcher::TEvRemoveConfigSubscriptionRequest, Handle); hFuncTraced(TEvConsole::TEvConfigNotificationResponse, Handle); IgnoreFunc(TEvConfigsDispatcher::TEvSetConfigSubscriptionResponse); + hFuncTraced(TEvConfigsDispatcher::TEvGetStateRequest, Handle); + hFuncTraced(TEvConfigsDispatcher::TEvGetStorageYamlRequest, Handle); // Resolve hFunc(TEvConsole::TEvGetNodeLabelsRequest, Handle); hFunc(TEvConsole::TEvFetchStartupConfigRequest, Handle); @@ -249,6 +289,7 @@ class TConfigsDispatcher : public TActorBootstrapped { const NKikimrConfig::TAppConfig BaseConfig; NKikimrConfig::TAppConfig CurrentConfig; const TString StartupConfigYaml; + const TString StartupStorageYaml; NKikimrConfig::TAppConfig CandidateStartupConfig; bool StartupConfigProcessError = false; bool StartupConfigProcessDiff = false; @@ -263,6 +304,10 @@ class TConfigsDispatcher : public TActorBootstrapped { TVector HttpRequests; TActorId CommonSubscriptionClient; TDeque> EventsQueue; + + // Observability: Track which replay path was used + bool LastReplayUsedSeedNodesPath = false; + bool LastReplayUsedDynamicConfigPath = false; THashMap SubscriptionsBySubscriber; THashMap SubscriptionsByKinds; @@ -285,6 +330,7 @@ TConfigsDispatcher::TConfigsDispatcher(const TConfigsDispatcherInitInfo& initInf , BaseConfig(initInfo.InitialConfig) , CurrentConfig(initInfo.InitialConfig) , StartupConfigYaml(initInfo.StartupConfigYaml) + , StartupStorageYaml(initInfo.StartupStorageYaml) , CandidateStartupConfig(initInfo.InitialConfig) , DebugInfo(initInfo.DebugInfo) , RecordedInitialConfiguratorDeps(std::move(initInfo.RecordedInitialConfiguratorDeps)) @@ -442,6 +488,20 @@ void TConfigsDispatcher::ReplyMonJson(TActorId mailbox) { response.InsertValue("yaml_config", MainYamlConfig); response.InsertValue("resolved_json_config", NJson::ReadJsonFastTree(ResolvedJsonConfig, true)); response.InsertValue("current_json_config", NJson::ReadJsonFastTree(NProtobufJson::Proto2Json(CurrentConfig, NYamlConfig::GetProto2JsonConfig()), true)); + + auto state = GetState(); + if (auto it = Labels.find("config_source"); it != Labels.end()) { + response.InsertValue("config_source", it->second); + } + if (auto it = Labels.find("configuration_version"); it != Labels.end()) { + response.InsertValue("configuration_version", it->second); + } + response.InsertValue("has_storage_yaml", state.HasStorageYaml); + if (state.HasStorageYaml) { + response.InsertValue("storage_yaml_size", static_cast(state.StorageYamlSize)); + } + response.InsertValue("last_replay_seed_nodes", state.LastReplayUsedSeedNodesPath); + response.InsertValue("last_replay_dynamic_config", state.LastReplayUsedDynamicConfigPath); if (DebugInfo) { // TODO: write custom json serializer for security fields @@ -652,6 +712,19 @@ void TConfigsDispatcher::Handle(TEvInterconnect::TEvNodesInfo::TPtr &ev) : s == &TThis::StateInit ? "StateInit" : "Unknown" ) << Endl; str << "YamlConfigEnabled: " << YamlConfigEnabled << Endl; + + str << Endl << "=== Configuration Source ===" << Endl; + auto state = GetState(); + str << state.ToDebugString() << Endl; + if (LastReplayUsedSeedNodesPath) { + str << "Last Replay Path: Seed Nodes (ConfigClient)" << Endl; + } else if (LastReplayUsedDynamicConfigPath) { + str << "Last Replay Path: Dynamic Config (DynConfigClient)" << Endl; + } else { + str << "Last Replay Path: Not yet executed" << Endl; + } + str << Endl; + str << "Subscriptions: " << Endl; for (auto &[kinds, subscription] : SubscriptionsByKinds) { str << "- Kinds: " << KindsToString(kinds) << Endl @@ -759,6 +832,34 @@ void TConfigsDispatcher::Handle(TEvInterconnect::TEvNodesInfo::TPtr &ev) } } str << "
" << Endl; + COLLAPSED_REF_CONTENT("storage-yaml-config", "Storage YAML Config (Seed Nodes)") { + if (!StartupStorageYaml.empty()) { + DIV() { + TAG(TH5) { + str << "Startup Storage Config (from seed nodes)" << Endl; + } + TAG_CLASS_STYLE(TDiv, "configs-dispatcher", "padding: 0 12px;") { + TAG_ATTRS(TDiv, {{"class", "yaml-sticky-btn-wrap fold-yaml-config yaml-btn-3"}, {"title", "fold"}}) { + DIV_CLASS("yaml-sticky-btn") { } + } + TAG_ATTRS(TDiv, {{"class", "yaml-sticky-btn-wrap unfold-yaml-config yaml-btn-2"}, {"title", "unfold"}}) { + DIV_CLASS("yaml-sticky-btn") { } + } + TAG_ATTRS(TDiv, {{"class", "yaml-sticky-btn-wrap copy-yaml-config yaml-btn-1"}, {"title", "copy"}}) { + DIV_CLASS("yaml-sticky-btn") { } + } + DIV_CLASS("yaml-config-item") { + str << StartupStorageYaml; + } + } + } + } else { + str << "
" << Endl; + str << "No storage config available. This is normal for non-seed-nodes initialization." << Endl; + str << "
" << Endl; + } + } + str << "
" << Endl; COLLAPSED_REF_CONTENT("resolved-yaml-config", "Resolved YAML config") { TAG_CLASS_STYLE(TDiv, "configs-dispatcher", "padding: 0 12px;") { TAG_ATTRS(TDiv, {{"class", "yaml-sticky-btn-wrap fold-yaml-config yaml-btn-3"}, {"id", "fold-resolved-yaml-config"}, {"title", "fold"}}) { @@ -818,9 +919,9 @@ void TConfigsDispatcher::Handle(TEvInterconnect::TEvNodesInfo::TPtr &ev) class TConfigurationResult : public IConfigurationResult + , public IStorageConfigResult { public: - // TODO make ref const NKikimrConfig::TAppConfig& GetConfig() const override { return Config; } @@ -829,10 +930,6 @@ class TConfigurationResult return !MainYamlConfig.empty(); } - const TString& GetMainYamlConfig() const override { - return MainYamlConfig; - } - TMap GetVolatileYamlConfigs() const override { return VolatileYamlConfigs; } @@ -845,10 +942,24 @@ class TConfigurationResult return DatabaseYamlConfig; } + const TString& GetStorageYamlConfig() const override { + return StorageYamlConfig; + } + + const TString& GetSourceAddress() const override { + return SourceAddress; + } + + const TString& GetMainYamlConfig() const override { + return MainYamlConfig; + } + NKikimrConfig::TAppConfig Config; TString MainYamlConfig; TMap VolatileYamlConfigs; TString DatabaseYamlConfig; + TString StorageYamlConfig; + TString SourceAddress; }; void TConfigsDispatcher::UpdateCandidateStartupConfig(TEvConsole::TEvConfigSubscriptionNotification::TPtr &ev) @@ -864,16 +975,41 @@ try { auto &rec = ev->Get()->Record; - auto dcClient = std::make_unique(); auto configs = std::make_shared(); - dcClient->SavedResult = configs; configs->Config = rec.GetRawConsoleConfig(); configs->MainYamlConfig = rec.GetMainYamlConfig(); if (rec.HasDatabaseYamlConfig()) { configs->DatabaseYamlConfig = rec.GetDatabaseYamlConfig(); } // TODO volatile - RecordedInitialConfiguratorDeps->DynConfigClient = std::move(dcClient); + + auto configSource = DetermineConfigSource(); + + LastReplayUsedSeedNodesPath = false; + LastReplayUsedDynamicConfigPath = false; + + switch (configSource) { + case EConfigSource::SeedNodes: + configs->StorageYamlConfig = StartupStorageYaml; + { + auto configClient = std::make_unique(); + configClient->SavedResult = configs; + RecordedInitialConfiguratorDeps->ConfigClient = std::move(configClient); + } + LastReplayUsedSeedNodesPath = true; + break; + + case EConfigSource::DynamicConfig: + case EConfigSource::Unknown: + { + auto dcClient = std::make_unique(); + dcClient->SavedResult = configs; + RecordedInitialConfiguratorDeps->DynConfigClient = std::move(dcClient); + } + LastReplayUsedDynamicConfigPath = true; + break; + } + auto deps = RecordedInitialConfiguratorDeps->GetDeps(); NConfig::TInitialConfigurator initCfg(deps); @@ -1051,9 +1187,11 @@ void TConfigsDispatcher::Handle(TEvConsole::TEvConfigSubscriptionNotification::T } if (CurrentStateFunc() == &TThis::StateInit) { + BLOG_D("Handle TEvConfigSubscriptionNotification: transitioning to StateWork"); Become(&TThis::StateWork); ProcessEnqueuedEvents(); } + BLOG_D("Handle TEvConfigSubscriptionNotification: exit"); } void TConfigsDispatcher::UpdateYamlVersion(const TSubscription::TPtr &subscription) const @@ -1295,6 +1433,15 @@ void TConfigsDispatcher::Handle(TEvConsole::TEvGetNodeConfigurationVersionReques Send(ev->Sender, response.release()); } +void TConfigsDispatcher::Handle(TEvConfigsDispatcher::TEvGetStateRequest::TPtr &ev) { + auto state = GetState(); + Send(ev->Sender, new TEvConfigsDispatcher::TEvGetStateResponse(std::move(state))); +} + +void TConfigsDispatcher::Handle(TEvConfigsDispatcher::TEvGetStorageYamlRequest::TPtr &ev) { + Send(ev->Sender, new TEvConfigsDispatcher::TEvGetStorageYamlResponse(StartupStorageYaml)); +} + IActor *CreateConfigsDispatcher(const TConfigsDispatcherInitInfo& initInfo) { return new TConfigsDispatcher(initInfo); } diff --git a/ydb/core/cms/console/configs_dispatcher.h b/ydb/core/cms/console/configs_dispatcher.h index cf60eb1a05f6..56fa38d4e0b3 100644 --- a/ydb/core/cms/console/configs_dispatcher.h +++ b/ydb/core/cms/console/configs_dispatcher.h @@ -1,5 +1,6 @@ #pragma once #include "defs.h" +#include "configs_dispatcher_observer.h" #include #include @@ -36,6 +37,12 @@ namespace TEvConfigsDispatcher { EvGetConfigResponse, EvRemoveConfigSubscriptionRequest, EvRemoveConfigSubscriptionResponse, + + // Observability events + EvGetStateRequest, + EvGetStateResponse, + EvGetStorageYamlRequest, + EvGetStorageYamlResponse, EvEnd }; @@ -106,6 +113,46 @@ namespace TEvConfigsDispatcher { struct TEvGetConfigResponse : public TEventLocal { std::shared_ptr Config; }; + + /** + * Request current state of ConfigsDispatcher. + * Response: TEvGetStateResponse + */ + struct TEvGetStateRequest : public TEventLocal { + TEvGetStateRequest() = default; + }; + + /** + * Response containing current state snapshot. + */ + struct TEvGetStateResponse : public TEventLocal { + TConfigsDispatcherState State; + + TEvGetStateResponse(TConfigsDispatcherState state) + : State(std::move(state)) + {} + }; + + /** + * Request storage YAML config (if available). + * Only available if initialized from seed nodes. + * Response: TEvGetStorageYamlResponse + */ + struct TEvGetStorageYamlRequest : public TEventLocal { + TEvGetStorageYamlRequest() = default; + }; + + /** + * Response containing storage YAML config. + * StorageYaml will be empty if not initialized from seed nodes. + */ + struct TEvGetStorageYamlResponse : public TEventLocal { + TString StorageYaml; + + TEvGetStorageYamlResponse(TString storageYaml) + : StorageYaml(std::move(storageYaml)) + {} + }; }; /** diff --git a/ydb/core/cms/console/configs_dispatcher_observer.h b/ydb/core/cms/console/configs_dispatcher_observer.h new file mode 100644 index 000000000000..c542794090da --- /dev/null +++ b/ydb/core/cms/console/configs_dispatcher_observer.h @@ -0,0 +1,66 @@ +#pragma once + +#include "defs.h" + +#include + +#include +#include + +namespace NKikimr::NConsole { + +/** + * Configuration source type enumeration. + * Indicates how the system was initialized. + */ +enum class EConfigSource { + SeedNodes, + DynamicConfig, + Unknown +}; + +/** + * State snapshot of ConfigsDispatcher. + * Used for observability, monitoring, and testing. + */ +struct TConfigsDispatcherState { + EConfigSource ConfigSource = EConfigSource::Unknown; + TString ConfigSourceLabel; + TString ConfigurationVersion; + bool HasStorageYaml = false; + size_t StorageYamlSize = 0; + bool YamlConfigEnabled = false; + size_t SubscriptionsCount = 0; + + bool LastReplayUsedSeedNodesPath = false; + bool LastReplayUsedDynamicConfigPath = false; + + TMap Labels; + + TString ToDebugString() const { + TStringStream ss; + ss << "ConfigSource: " << ConfigSourceLabel; + switch (ConfigSource) { + case EConfigSource::SeedNodes: + ss << " (seed nodes - uses ConfigClient)"; + break; + case EConfigSource::DynamicConfig: + ss << " (dynamic config - uses DynConfigClient)"; + break; + case EConfigSource::Unknown: + ss << " (unknown)"; + break; + } + ss << "\nConfigurationVersion: " << ConfigurationVersion; + ss << "\nHasStorageYaml: " << (HasStorageYaml ? "yes" : "no"); + if (HasStorageYaml) { + ss << " (" << StorageYamlSize << " bytes)"; + } + ss << "\nYamlConfigEnabled: " << YamlConfigEnabled; + ss << "\nSubscriptionsCount: " << SubscriptionsCount; + return ss.Str(); + } +}; + +} // namespace NKikimr::NConsole + diff --git a/ydb/core/cms/console/configs_dispatcher_ut.cpp b/ydb/core/cms/console/configs_dispatcher_ut.cpp index b15deff53275..0a9e3b4f57b0 100644 --- a/ydb/core/cms/console/configs_dispatcher_ut.cpp +++ b/ydb/core/cms/console/configs_dispatcher_ut.cpp @@ -1,6 +1,7 @@ #include "configs_dispatcher.h" #include "ut_helpers.h" +#include #include #include #include @@ -921,4 +922,152 @@ selector_config: [] UNIT_ASSERT_VALUES_EQUAL(controlValue, 1); } } + +Y_UNIT_TEST_SUITE(TConfigsDispatcherObservabilityTests) { + + TActorId GetRuntimeDispatcherId(TTenantTestRuntime& runtime) { + return MakeConfigsDispatcherID(runtime.GetNodeId(0)); + } + + TConfigsDispatcherState QueryState(TTenantTestRuntime& runtime, TActorId dispatcherId) { + runtime.Send(new IEventHandle(dispatcherId, runtime.Sender, new TEvConfigsDispatcher::TEvGetStateRequest())); + TAutoPtr handle; + auto response = runtime.GrabEdgeEventRethrow(handle); + return response->State; + } + + TString QueryStorageYaml(TTenantTestRuntime& runtime, TActorId dispatcherId) { + runtime.Send(new IEventHandle(dispatcherId, runtime.Sender, new TEvConfigsDispatcher::TEvGetStorageYamlRequest())); + TAutoPtr handle; + auto response = runtime.GrabEdgeEventRethrow(handle); + return response->StorageYaml; + } + + TTenantTestConfig ConfigWithoutDispatcher() { + TTenantTestConfig cfg = DefaultConsoleTestConfig(); + cfg.CreateConfigsDispatcher = false; + return cfg; + } + + Y_UNIT_TEST(TestGetStateRequestResponse) { + TTenantTestRuntime runtime(DefaultConsoleTestConfig()); + InitConfigsDispatcher(runtime); + + TActorId dispatcherId = GetRuntimeDispatcherId(runtime); + auto state = QueryState(runtime, dispatcherId); + + UNIT_ASSERT(!state.ConfigSourceLabel.empty() || state.ConfigSource != EConfigSource::Unknown); + UNIT_ASSERT(state.SubscriptionsCount >= 0); + } + + Y_UNIT_TEST(TestGetStorageYamlRequestResponse) { + TTenantTestRuntime runtime(DefaultConsoleTestConfig()); + InitConfigsDispatcher(runtime); + + TActorId dispatcherId = GetRuntimeDispatcherId(runtime); + TString storageYaml = QueryStorageYaml(runtime, dispatcherId); + + UNIT_ASSERT(storageYaml.empty()); + } + + Y_UNIT_TEST(TestSeedNodesInitialization) { + NKikimrConfig::TAppConfig config; + TString storageYaml = "storage:\n nodes:\n - node1:2135\n - node2:2135\n"; + config.SetStartupStorageYaml(storageYaml); + + NConfig::TConfigsDispatcherInitInfo initInfo; + initInfo.InitialConfig = config; + initInfo.StartupConfigYaml = "config:\n log_config:\n cluster_name: test\n"; + initInfo.StartupStorageYaml = storageYaml; + initInfo.Labels["config_source"] = "seed_nodes"; + initInfo.Labels["configuration_version"] = "v2"; + initInfo.DebugInfo = NConfig::TDebugInfo{}; + + TTenantTestRuntime runtime(ConfigWithoutDispatcher(), config); + + auto* dispatcher = NConsole::CreateConfigsDispatcher(initInfo); + TActorId dispatcherId = runtime.Register(dispatcher); + runtime.EnableScheduleForActor(dispatcherId, true); + + { + TDispatchOptions options; + options.FinalEvents.emplace_back(TDispatchOptions::TFinalEventCondition(TEvConsole::EvConfigSubscriptionNotification)); + runtime.DispatchEvents(options); + } + + auto state = QueryState(runtime, dispatcherId); + + UNIT_ASSERT_EQUAL(state.ConfigSource, EConfigSource::SeedNodes); + UNIT_ASSERT_VALUES_EQUAL(state.ConfigSourceLabel, "seed_nodes"); + UNIT_ASSERT_VALUES_EQUAL(state.ConfigurationVersion, "v2"); + UNIT_ASSERT(state.HasStorageYaml); + UNIT_ASSERT(state.StorageYamlSize > 0); + + TString retrievedStorageYaml = QueryStorageYaml(runtime, dispatcherId); + UNIT_ASSERT_VALUES_EQUAL(retrievedStorageYaml, storageYaml); + } + + Y_UNIT_TEST(TestDynamicConfigInitialization) { + + NKikimrConfig::TAppConfig config; + + NConfig::TConfigsDispatcherInitInfo initInfo; + initInfo.InitialConfig = config; + initInfo.StartupConfigYaml = "config:\n log_config:\n cluster_name: test\n"; + initInfo.Labels["config_source"] = "dynamic"; + initInfo.Labels["configuration_version"] = "v1"; + initInfo.DebugInfo = NConfig::TDebugInfo{}; + + TTenantTestRuntime runtime(ConfigWithoutDispatcher(), config); + + auto* dispatcher = NConsole::CreateConfigsDispatcher(initInfo); + TActorId dispatcherId = runtime.Register(dispatcher); + runtime.EnableScheduleForActor(dispatcherId, true); + + { + TDispatchOptions options; + options.FinalEvents.emplace_back(TDispatchOptions::TFinalEventCondition(TEvConsole::EvConfigSubscriptionNotification)); + runtime.DispatchEvents(options); + } + + auto state = QueryState(runtime, dispatcherId); + + UNIT_ASSERT_EQUAL(state.ConfigSource, EConfigSource::DynamicConfig); + UNIT_ASSERT_VALUES_EQUAL(state.ConfigSourceLabel, "dynamic"); + UNIT_ASSERT_VALUES_EQUAL(state.ConfigurationVersion, "v1"); + UNIT_ASSERT(!state.HasStorageYaml); + UNIT_ASSERT_VALUES_EQUAL(state.StorageYamlSize, 0); + + TString retrievedStorageYaml = QueryStorageYaml(runtime, dispatcherId); + UNIT_ASSERT(retrievedStorageYaml.empty()); + } + + Y_UNIT_TEST(TestUnknownConfigSource) { + NKikimrConfig::TAppConfig config; + + NConfig::TConfigsDispatcherInitInfo initInfo; + initInfo.InitialConfig = config; + initInfo.StartupConfigYaml = "config: {}\n"; + initInfo.DebugInfo = NConfig::TDebugInfo{}; + + TTenantTestRuntime runtime(ConfigWithoutDispatcher(), config); + + auto* dispatcher = NConsole::CreateConfigsDispatcher(initInfo); + TActorId dispatcherId = runtime.Register(dispatcher); + runtime.EnableScheduleForActor(dispatcherId, true); + + { + TDispatchOptions options; + options.FinalEvents.emplace_back(TDispatchOptions::TFinalEventCondition(TEvConsole::EvConfigSubscriptionNotification)); + runtime.DispatchEvents(options); + } + + auto state = QueryState(runtime, dispatcherId); + + UNIT_ASSERT_EQUAL(state.ConfigSource, EConfigSource::DynamicConfig); + UNIT_ASSERT(state.ConfigSourceLabel.empty()); + UNIT_ASSERT(!state.HasStorageYaml); + } +} + } // namespace NKikimr diff --git a/ydb/core/cms/console/ut_configs_dispatcher/ya.make b/ydb/core/cms/console/ut_configs_dispatcher/ya.make new file mode 100644 index 000000000000..ee3194bfca69 --- /dev/null +++ b/ydb/core/cms/console/ut_configs_dispatcher/ya.make @@ -0,0 +1,23 @@ +UNITTEST_FOR(ydb/core/cms/console) + +FORK_SUBTESTS() + +SIZE(MEDIUM) + +PEERDIR( + library/cpp/getopt + library/cpp/protobuf/util + library/cpp/regex/pcre + library/cpp/svnversion + ydb/core/testlib/default +) + +YQL_LAST_ABI_VERSION() + +SRCS( + configs_cache_ut.cpp + configs_dispatcher_ut.cpp +) + +END() + diff --git a/ydb/core/cms/console/ut/ya.make b/ydb/core/cms/console/ut_console/ya.make similarity index 90% rename from ydb/core/cms/console/ut/ya.make rename to ydb/core/cms/console/ut_console/ya.make index 6a242aa2eea4..b7d21968d51f 100644 --- a/ydb/core/cms/console/ut/ya.make +++ b/ydb/core/cms/console/ut_console/ya.make @@ -15,8 +15,6 @@ PEERDIR( YQL_LAST_ABI_VERSION() SRCS( - configs_cache_ut.cpp - configs_dispatcher_ut.cpp console_ut_tenants.cpp console_ut_configs.cpp feature_flags_configurator_ut.cpp @@ -28,3 +26,4 @@ SRCS( ) END() + diff --git a/ydb/core/cms/console/ya.make b/ydb/core/cms/console/ya.make index ec420b7620c5..6cfbd674670d 100644 --- a/ydb/core/cms/console/ya.make +++ b/ydb/core/cms/console/ya.make @@ -9,6 +9,7 @@ SRCS( configs_config.h configs_dispatcher.cpp configs_dispatcher.h + configs_dispatcher_observer.h configs_dispatcher_proxy.h configs_dispatcher_proxy.cpp console.cpp @@ -115,5 +116,6 @@ RECURSE( ) RECURSE_FOR_TESTS( - ut + ut_configs_dispatcher + ut_console ) diff --git a/ydb/core/config/init/init.h b/ydb/core/config/init/init.h index 374ddb29781e..18a5608bd7af 100644 --- a/ydb/core/config/init/init.h +++ b/ydb/core/config/init/init.h @@ -254,6 +254,7 @@ struct TDebugInfo { struct TConfigsDispatcherInitInfo { NKikimrConfig::TAppConfig InitialConfig; TString StartupConfigYaml; + TString StartupStorageYaml; TMap Labels; std::variant ItemsServeRules; std::optional DebugInfo; diff --git a/ydb/core/config/init/init_impl.h b/ydb/core/config/init/init_impl.h index 0b2536ffabae..5d3c5fb52f85 100644 --- a/ydb/core/config/init/init_impl.h +++ b/ydb/core/config/init/init_impl.h @@ -1506,6 +1506,9 @@ class TInitialConfiguratorImpl clusterName = ClusterName; configsDispatcherInitInfo.InitialConfig = appConfig; configsDispatcherInitInfo.StartupConfigYaml = appConfig.GetStartupConfigYaml(); + if (appConfig.HasStartupStorageYaml()) { + configsDispatcherInitInfo.StartupStorageYaml = appConfig.GetStartupStorageYaml(); + } configsDispatcherInitInfo.ItemsServeRules = std::monostate{}, configsDispatcherInitInfo.Labels = Labels; configsDispatcherInitInfo.Labels["configuration_version"] = appConfig.GetConfigDirPath() ? "v2" : "v1";