Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reload config #315

Merged
merged 6 commits into from
Oct 6, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget

import java.time.Instant
import java.time.ZoneId
import java.time.format.DateTimeFormatter
Expand Down Expand Up @@ -124,14 +126,10 @@ dependencies {
}

compileKotlin {
kotlinOptions {
jvmTarget = "20"
}
compilerOptions.jvmTarget.set(JvmTarget.JVM_20)
}
compileTestKotlin {
kotlinOptions {
jvmTarget = "20"
}
compilerOptions.jvmTarget.set(JvmTarget.JVM_20)
}

test {
Expand Down
Binary file added foundation/gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
5 changes: 5 additions & 0 deletions foundation/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,23 @@ class ChainOptions {
val validateChain: Boolean,
)

open class DefaultOptions : PartialOptions() {
var chains: List<String>? = null
data class DefaultOptions(
var chains: List<String>? = null,
var options: PartialOptions? = null
}
)

open class PartialOptions {
data class PartialOptions(
var disableValidation: Boolean? = null,
var disableUpstreamValidation: Boolean? = null,
var validationInterval: Int? = null,
var timeout: Duration? = null,
var providesBalance: Boolean? = null,
var validatePeers: Boolean? = null,
var validateCalllimit: Boolean? = null,
var minPeers: Int? = null,
var validateSyncing: Boolean? = null,
var validateChain: Boolean? = null
) {
companion object {
@JvmStatic
fun getDefaults(): PartialOptions {
Expand All @@ -31,29 +42,6 @@ class ChainOptions {
}
}

var disableValidation: Boolean? = null
var disableUpstreamValidation: Boolean? = null
var validationInterval: Int? = null
set(value) {
require(value == null || value > 0) {
"validation-interval must be a positive number: $value"
}
field = value
}
var timeout: Duration? = null
var providesBalance: Boolean? = null
var validatePeers: Boolean? = null
var validateCalllimit: Boolean? = null
var minPeers: Int? = null
set(value) {
require(value == null || value >= 0) {
"min-peers must be a positive number: $value"
}
field = value
}
var validateSyncing: Boolean? = null
var validateChain: Boolean? = null

fun merge(overwrites: PartialOptions?): PartialOptions {
if (overwrites == null) {
return this
Expand Down
6 changes: 6 additions & 0 deletions src/main/kotlin/io/emeraldpay/dshackle/Config.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import io.emeraldpay.dshackle.config.HealthConfig
import io.emeraldpay.dshackle.config.MainConfig
import io.emeraldpay.dshackle.config.MainConfigReader
import io.emeraldpay.dshackle.config.MonitoringConfig
import io.emeraldpay.dshackle.config.ReloadConfiguration
import io.emeraldpay.dshackle.config.SignatureConfig
import io.emeraldpay.dshackle.config.TokensConfig
import io.emeraldpay.dshackle.config.UpstreamsConfig
Expand Down Expand Up @@ -159,4 +160,9 @@ open class Config(
open fun authorizationConfig(mainConfig: MainConfig): AuthorizationConfig {
return mainConfig.authorization
}

@Bean
open fun reloadConfiguration(mainConfig: MainConfig): ReloadConfiguration {
return mainConfig.reloadConfiguration
}
}
2 changes: 2 additions & 0 deletions src/main/kotlin/io/emeraldpay/dshackle/FileResolver.kt
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,6 @@ open class FileResolver(
}
return File(baseDir, path)
}

fun file() = baseDir
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class DynamicMergeFlux<K : Any, T>(private val scheduler: Scheduler) {

fun stop() {
sources.forEach { (_, d) -> d.dispose() }
sources.clear()
merge.emitComplete { _, res -> res == Sinks.EmitResult.FAIL_NON_SERIALIZED }
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ class MainConfig {
var compression: CompressionConfig = CompressionConfig.default()
var chains: ChainsConfig = ChainsConfig.default()
var authorization: AuthorizationConfig = AuthorizationConfig.default()
var reloadConfiguration: ReloadConfiguration = ReloadConfiguration.default()
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class MainConfigReader(
private val compressionConfigReader = CompressionConfigReader()
private val chainsConfigReader = ChainsConfigReader(optionsReader)
private val authorizationConfigReader = AuthorizationConfigReader()
private val reloadConfigurationReader = ReloadConfigurationReader()

override fun read(input: MappingNode?): MainConfig {
val config = MainConfig()
Expand Down Expand Up @@ -87,6 +88,9 @@ class MainConfigReader(
authorizationConfigReader.read(input).let {
config.authorization = it
}
reloadConfigurationReader.read(input).let {
config.reloadConfiguration = it
}
return config
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package io.emeraldpay.dshackle.config

import io.emeraldpay.dshackle.foundation.YamlConfigReader
import org.yaml.snakeyaml.nodes.MappingNode

data class ReloadConfiguration(
val port: Int,
) {
companion object {
fun default() = ReloadConfiguration(8093)
}
}

class ReloadConfigurationReader : YamlConfigReader<ReloadConfiguration>() {

override fun read(input: MappingNode?): ReloadConfiguration {
val reload = getMapping(input, "reload") ?: return ReloadConfiguration.default()

val port = getValueAsInt(reload, "port") ?: return ReloadConfiguration.default()

return ReloadConfiguration(port)
}
}
89 changes: 69 additions & 20 deletions src/main/kotlin/io/emeraldpay/dshackle/config/UpstreamsConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,23 @@ import java.util.Arrays
import java.util.Locale
import java.util.concurrent.ConcurrentHashMap

open class UpstreamsConfig {
var defaultOptions: MutableList<ChainOptions.DefaultOptions> = ArrayList()
var upstreams: MutableList<Upstream<*>> = ArrayList<Upstream<*>>()

class Upstream<T : UpstreamConnection> {
var id: String? = null
var nodeId: Int? = null
var chain: String? = null
var options: ChainOptions.PartialOptions? = null
var isEnabled = true
var connection: T? = null
val labels = Labels()
var methods: Methods? = null
var methodGroups: MethodGroups? = null
var role: UpstreamRole = UpstreamRole.PRIMARY
data class UpstreamsConfig(
var defaultOptions: MutableList<ChainOptions.DefaultOptions> = ArrayList(),
var upstreams: MutableList<Upstream<*>> = ArrayList(),
) {

data class Upstream<T : UpstreamConnection>(
var id: String? = null,
var nodeId: Int? = null,
var chain: String? = null,
var options: ChainOptions.PartialOptions? = null,
var isEnabled: Boolean = true,
var connection: T? = null,
val labels: Labels = Labels(),
var methods: Methods? = null,
var methodGroups: MethodGroups? = null,
var role: UpstreamRole = UpstreamRole.PRIMARY,
) {

@Suppress("UNCHECKED_CAST")
fun <Z : UpstreamConnection> cast(type: Class<Z>): Upstream<Z> {
Expand All @@ -58,6 +60,19 @@ open class UpstreamsConfig {

open class RpcConnection : UpstreamConnection() {
var rpc: HttpEndpoint? = null

override fun equals(other: Any?): Boolean {
KirillPamPam marked this conversation as resolved.
Show resolved Hide resolved
if (this === other) return true
if (other !is RpcConnection) return false

if (rpc != other.rpc) return false

return true
}

override fun hashCode(): Int {
return rpc?.hashCode() ?: 0
}
}

class GrpcConnection : UpstreamConnection() {
Expand Down Expand Up @@ -85,6 +100,24 @@ open class UpstreamsConfig {
ConnectorMode.parse(connectorMode!!)
}
}

override fun equals(other: Any?): Boolean {
KirillPamPam marked this conversation as resolved.
Show resolved Hide resolved
if (this === other) return true
if (other !is EthereumConnection) return false
if (!super.equals(other)) return false

if (ws != other.ws) return false
if (connectorMode != other.connectorMode) return false

return true
}

override fun hashCode(): Int {
var result = super.hashCode()
result = 31 * result + (ws?.hashCode() ?: 0)
result = 31 * result + (connectorMode?.hashCode() ?: 0)
return result
}
}

class BitcoinConnection : RpcConnection() {
Expand All @@ -95,19 +128,35 @@ open class UpstreamsConfig {
class EthereumPosConnection : UpstreamConnection() {
var execution: EthereumConnection? = null
var upstreamRating: Int = 0

override fun equals(other: Any?): Boolean {
KirillPamPam marked this conversation as resolved.
Show resolved Hide resolved
if (this === other) return true
if (other !is EthereumPosConnection) return false

if (execution != other.execution) return false
if (upstreamRating != other.upstreamRating) return false

return true
}

override fun hashCode(): Int {
var result = execution?.hashCode() ?: 0
result = 31 * result + upstreamRating
return result
}
}

data class BitcoinZeroMq(
val host: String = "127.0.0.1",
val port: Int,
)

class HttpEndpoint(val url: URI) {
data class HttpEndpoint(val url: URI) {
var basicAuth: AuthConfig.ClientBasicAuth? = null
var tls: AuthConfig.ClientTlsAuth? = null
}

class WsEndpoint(val url: URI) {
data class WsEndpoint(val url: URI) {
var origin: URI? = null
var basicAuth: AuthConfig.ClientBasicAuth? = null
var frameSize: Int? = null
Expand Down Expand Up @@ -159,17 +208,17 @@ open class UpstreamsConfig {
}
}

class Methods(
data class Methods(
val enabled: Set<Method>,
val disabled: Set<Method>,
)

class MethodGroups(
data class MethodGroups(
val enabled: Set<String>,
val disabled: Set<String>,
)

class Method(
data class Method(
val name: String,
val quorum: String? = null,
val static: String? = null,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.emeraldpay.dshackle.config.reload

import io.emeraldpay.dshackle.Config
import io.emeraldpay.dshackle.FileResolver
import io.emeraldpay.dshackle.config.MainConfig
import io.emeraldpay.dshackle.config.UpstreamsConfig
import io.emeraldpay.dshackle.config.UpstreamsConfigReader
import io.emeraldpay.dshackle.foundation.ChainOptionsReader
import org.springframework.stereotype.Component

@Component
class ReloadConfigService(
private val config: Config,
fileResolver: FileResolver,
private val mainConfig: MainConfig,

) {
private val optionsReader = ChainOptionsReader()
private val upstreamsConfigReader = UpstreamsConfigReader(fileResolver, optionsReader)

fun readUpstreamsConfig() = upstreamsConfigReader.read(config.getConfigPath().inputStream())!!

fun currentUpstreamsConfig() = mainConfig.upstreams!!

fun updateUpstreamsConfig(newConfig: UpstreamsConfig) {
mainConfig.upstreams = newConfig
}
}
Loading
Loading