From ef32bd4c5386c45fd5cf29d1a412fc2125b30bd8 Mon Sep 17 00:00:00 2001 From: KirillPamPam Date: Tue, 18 Jun 2024 14:12:02 +0400 Subject: [PATCH] Fix config reload (#510) --- .../kotlin/io/emeraldpay/dshackle/Global.kt | 2 ++ .../io/emeraldpay/dshackle/config/MainConfig.kt | 17 +++++++++++++++++ .../dshackle/config/UpstreamsConfig.kt | 13 ++++++++++++- .../config/reload/ReloadConfigService.kt | 2 +- .../dshackle/config/reload/ReloadConfigSetup.kt | 4 ++-- .../dshackle/config/reload/ReloadConfigTest.kt | 1 + 6 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/io/emeraldpay/dshackle/Global.kt b/src/main/kotlin/io/emeraldpay/dshackle/Global.kt index 5a7327979..32118b677 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/Global.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/Global.kt @@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.module.SimpleModule import com.fasterxml.jackson.datatype.jdk8.Jdk8Module import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule +import com.fasterxml.jackson.module.kotlin.registerKotlinModule import io.emeraldpay.dshackle.upstream.ChainRequest import io.emeraldpay.dshackle.upstream.ChainResponse import io.emeraldpay.dshackle.upstream.beaconchain.BeaconChainBlockHeader @@ -81,6 +82,7 @@ class Global { objectMapper.registerModule(module) objectMapper.registerModule(Jdk8Module()) objectMapper.registerModule(JavaTimeModule()) + objectMapper.registerKotlinModule() objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) objectMapper .setDateFormat(SimpleDateFormat("yyyy-MM-dd\'T\'HH:mm:ss.SSS")) diff --git a/src/main/kotlin/io/emeraldpay/dshackle/config/MainConfig.kt b/src/main/kotlin/io/emeraldpay/dshackle/config/MainConfig.kt index 9146b3760..23b4fb7a0 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/config/MainConfig.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/config/MainConfig.kt @@ -15,6 +15,9 @@ */ package io.emeraldpay.dshackle.config +import com.fasterxml.jackson.module.kotlin.readValue +import io.emeraldpay.dshackle.Global + class MainConfig { var host = "127.0.0.1" var port = 2449 @@ -24,6 +27,17 @@ class MainConfig { var index: IndexConfig? = null var proxy: ProxyConfig? = null var upstreams: UpstreamsConfig? = null + set(value) { + field = value + value?.let { cfg -> + // we need to store the initial config we've loaded from dshackle.yaml + // because we can change the current config on the fly + // during config reload we must compare the pure configs + initialConfig = Global.objectMapper.readValue( + Global.objectMapper.writeValueAsBytes(cfg), + ) + } + } var tokens: TokensConfig? = null var monitoring: MonitoringConfig = MonitoringConfig.default() var accessLogConfig: AccessLogConfig = AccessLogConfig.default() @@ -32,4 +46,7 @@ class MainConfig { var compression: CompressionConfig = CompressionConfig.default() var chains: ChainsConfig = ChainsConfig.default() var authorization: AuthorizationConfig = AuthorizationConfig.default() + + var initialConfig: UpstreamsConfig? = null + private set } diff --git a/src/main/kotlin/io/emeraldpay/dshackle/config/UpstreamsConfig.kt b/src/main/kotlin/io/emeraldpay/dshackle/config/UpstreamsConfig.kt index 1d44baade..c7e697ae9 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/config/UpstreamsConfig.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/config/UpstreamsConfig.kt @@ -16,6 +16,8 @@ */ package io.emeraldpay.dshackle.config +import com.fasterxml.jackson.annotation.JsonSubTypes +import com.fasterxml.jackson.annotation.JsonTypeInfo import io.emeraldpay.dshackle.foundation.ChainOptions import io.emeraldpay.dshackle.upstream.generic.connectors.GenericConnectorFactory.ConnectorMode import java.net.URI @@ -25,7 +27,7 @@ import java.util.concurrent.ConcurrentHashMap data class UpstreamsConfig( var defaultOptions: MutableList = ArrayList(), - var upstreams: MutableList> = ArrayList(), + var upstreams: MutableList> = ArrayList(), ) { data class Upstream( @@ -56,6 +58,15 @@ data class UpstreamsConfig( FALLBACK, } + @JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + ) + @JsonSubTypes( + JsonSubTypes.Type(value = RpcConnection::class), + JsonSubTypes.Type(value = GrpcConnection::class), + JsonSubTypes.Type(value = EthereumPosConnection::class), + JsonSubTypes.Type(value = BitcoinConnection::class), + ) open class UpstreamConnection data class RpcConnection( diff --git a/src/main/kotlin/io/emeraldpay/dshackle/config/reload/ReloadConfigService.kt b/src/main/kotlin/io/emeraldpay/dshackle/config/reload/ReloadConfigService.kt index e5ced0455..76135cb15 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/config/reload/ReloadConfigService.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/config/reload/ReloadConfigService.kt @@ -20,7 +20,7 @@ class ReloadConfigService( fun readUpstreamsConfig() = upstreamsConfigReader.read(config.getConfigPath().inputStream())!! - fun currentUpstreamsConfig() = mainConfig.upstreams!! + fun currentUpstreamsConfig() = mainConfig.initialConfig!! fun updateUpstreamsConfig(newConfig: UpstreamsConfig) { mainConfig.upstreams = newConfig diff --git a/src/main/kotlin/io/emeraldpay/dshackle/config/reload/ReloadConfigSetup.kt b/src/main/kotlin/io/emeraldpay/dshackle/config/reload/ReloadConfigSetup.kt index 49b6d7ab3..ecece93c0 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/config/reload/ReloadConfigSetup.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/config/reload/ReloadConfigSetup.kt @@ -78,10 +78,10 @@ class ReloadConfigSetup( .toSet() val upstreamsToAdd = upstreamsAnalyzeData.added - reloadConfigUpstreamService.reloadUpstreams(chainsToReload, upstreamsToRemove, upstreamsToAdd, newUpstreamsConfig) - reloadConfigService.updateUpstreamsConfig(newUpstreamsConfig) + reloadConfigUpstreamService.reloadUpstreams(chainsToReload, upstreamsToRemove, upstreamsToAdd, newUpstreamsConfig) + return true } diff --git a/src/test/kotlin/io/emeraldpay/dshackle/config/reload/ReloadConfigTest.kt b/src/test/kotlin/io/emeraldpay/dshackle/config/reload/ReloadConfigTest.kt index 4675a5a4e..12c686519 100644 --- a/src/test/kotlin/io/emeraldpay/dshackle/config/reload/ReloadConfigTest.kt +++ b/src/test/kotlin/io/emeraldpay/dshackle/config/reload/ReloadConfigTest.kt @@ -153,6 +153,7 @@ class ReloadConfigTest { val initialConfigFile = ResourceUtils.getFile("classpath:configs/upstreams-initial.yaml") val initialConfig = upstreamsConfigReader.read(initialConfigFile.inputStream())!! mainConfig.upstreams = initialConfig + mainConfig.upstreams?.upstreams?.get(0)?.methodGroups = UpstreamsConfig.MethodGroups(setOf("new"), setOf()) val reloadConfigUpstreamService = mock()